Failed Conditions
Pull Request — develop (#6599)
by Michael
131:05 queued 63:47
created

EntityRepositoryTest   D

Complexity

Total Complexity 71

Size/Duplication

Total Lines 1096
Duplicated Lines 29.2 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 71
lcom 1
cbo 11
dl 320
loc 1096
rs 4.886
c 0
b 0
f 0

69 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 5 1
A tearDown() 0 7 2
B loadFixture() 0 39 1
A loadAssociatedFixture() 0 21 1
B loadFixtureUserEmail() 0 43 1
A buildUser() 0 13 1
A buildAddress() 0 13 1
A testBasicFind() 10 10 1
A testFindByField() 11 11 1
A testFindByAssociationWithIntegerAsParameter() 23 23 1
A testFindByAssociationWithObjectAsParameter() 23 23 1
A testFindFieldByMagicCall() 11 11 1
A testFindAll() 8 8 1
A testFindByAlias() 0 12 1
A testCount() 0 14 1
A testCountBy() 0 8 1
A testExceptionIsThrownWhenCallingFindByWithoutParameter() 0 4 1
A testExceptionIsThrownWhenUsingInvalidFieldName() 0 4 1
A testPessimisticReadLockWithoutTransaction_ThrowsException() 0 7 1
A testPessimisticWriteLockWithoutTransaction_ThrowsException() 0 7 1
A testOptimisticLockUnversionedEntity_ThrowsException() 0 7 1
A testIdentityMappedOptimisticLockUnversionedEntity_ThrowsException() 0 17 1
A testFindMagicCallByNullValue() 9 9 1
A testInvalidMagicCall() 0 7 1
A testFindByAssociationKey_ExceptionOnInverseSide() 0 10 1
A testFindOneByAssociationKey() 9 9 1
A testFindOneByOrderBy() 0 10 1
A testFindByAssociationKey() 10 10 1
A testFindAssociationByMagicCall() 10 10 1
A testFindOneAssociationByMagicCall() 0 9 1
A testValidNamedQueryRetrieval() 0 9 1
A testInvalidNamedQueryRetrieval() 0 8 1
A testIsNullCriteriaDoesNotGenerateAParameter() 0 9 1
A testIsNullCriteria() 9 9 1
A testFindByLimitOffset() 0 14 1
A testFindByOrderBy() 0 13 1
A testFindByOrderByAssociation() 0 14 1
A testFindFieldByMagicCallOrderBy() 0 18 1
A testFindFieldByMagicCallLimitOffset() 0 12 1
A testDefaultRepositoryClassName() 0 20 1
A testSetDefaultRepositoryInvalidClassError() 0 5 1
A testSingleRepositoryInstanceForDifferentEntityAliases() 0 12 1
A testCanRetrieveRepositoryFromClassNameWithLeadingBackslash() 0 7 1
A testInvalidOrderByAssociation() 0 5 1
A testInvalidOrientation() 8 8 1
A testFindByAssociationArray() 0 9 1
A testMatchingEmptyCriteria() 9 9 1
A testMatchingCriteriaEqComparison() 0 11 1
A testMatchingCriteriaNeqComparison() 11 11 1
A testMatchingCriteriaInComparison() 11 11 1
A testMatchingCriteriaNotInComparison() 11 11 1
A testMatchingCriteriaLtComparison() 0 11 1
A testMatchingCriteriaLeComparison() 0 11 1
A testMatchingCriteriaGtComparison() 0 11 1
A testMatchingCriteriaGteComparison() 0 11 1
A testMatchingCriteriaAssocationByObjectInMemory() 19 19 1
A testMatchingCriteriaAssocationInWithArray() 19 19 1
A testMatchingCriteriaContainsComparison() 0 15 1
A testMatchingCriteriaStartsWithComparison() 15 15 1
A testMatchingCriteriaEndsWithComparison() 15 15 1
B testMatchingCriteriaNullAssocComparison() 0 25 1
A testCreateResultSetMappingBuilder() 0 8 1
A testFindByFieldInjectionPrevented() 8 8 1
A testFindOneByFieldInjectionPrevented() 8 8 1
A testMatchingInjectionPrevented() 0 13 1
A testFindInjectionPrevented() 8 8 1
A testFindByNullValueInInCondition() 21 21 1
B testFindByNullValueInMultipleInCriteriaValues() 24 24 1
B testFindMultipleByNullValueInMultipleInCriteriaValues() 0 27 2

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 EntityRepositoryTest 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 EntityRepositoryTest, and based on these observations, apply Extract Interface, too.

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 tearDown()
38
    {
39
        if ($this->em) {
40
            $this->em->getConfiguration()->setEntityNamespaces([]);
41
        }
42
        parent::tearDown();
43
    }
44
45
    public function loadFixture()
46
    {
47
        $user = new CmsUser;
48
        $user->name = 'Roman';
49
        $user->username = 'romanb';
50
        $user->status = 'freak';
51
        $this->em->persist($user);
52
53
        $user2 = new CmsUser;
54
        $user2->name = 'Guilherme';
55
        $user2->username = 'gblanco';
56
        $user2->status = 'dev';
57
        $this->em->persist($user2);
58
59
        $user3 = new CmsUser;
60
        $user3->name = 'Benjamin';
61
        $user3->username = 'beberlei';
62
        $user3->status = null;
63
        $this->em->persist($user3);
64
65
        $user4 = new CmsUser;
66
        $user4->name = 'Alexander';
67
        $user4->username = 'asm89';
68
        $user4->status = 'dev';
69
        $this->em->persist($user4);
70
71
        $this->em->flush();
72
73
        $user1Id = $user->getId();
74
75
        unset($user);
76
        unset($user2);
77
        unset($user3);
78
        unset($user4);
79
80
        $this->em->clear();
81
82
        return $user1Id;
83
    }
84
85
    public function loadAssociatedFixture()
86
    {
87
        $address = new CmsAddress();
88
        $address->city = "Berlin";
89
        $address->country = "Germany";
90
        $address->street = "Foostreet";
91
        $address->zip = "12345";
92
93
        $user = new CmsUser();
94
        $user->name = 'Roman';
95
        $user->username = 'romanb';
96
        $user->status = 'freak';
97
        $user->setAddress($address);
98
99
        $this->em->persist($user);
100
        $this->em->persist($address);
101
        $this->em->flush();
102
        $this->em->clear();
103
104
        return [$user->id, $address->id];
105
    }
106
107
    public function loadFixtureUserEmail()
108
    {
109
        $user1 = new CmsUser();
110
        $user2 = new CmsUser();
111
        $user3 = new CmsUser();
112
113
        $email1 = new CmsEmail();
114
        $email2 = new CmsEmail();
115
        $email3 = new CmsEmail();
116
117
        $user1->name     = 'Test 1';
118
        $user1->username = 'test1';
119
        $user1->status   = 'active';
120
121
        $user2->name     = 'Test 2';
122
        $user2->username = 'test2';
123
        $user2->status   = 'active';
124
125
        $user3->name     = 'Test 3';
126
        $user3->username = 'test3';
127
        $user3->status   = 'active';
128
129
        $email1->email   = '[email protected]';
130
        $email2->email   = '[email protected]';
131
        $email3->email   = '[email protected]';
132
133
        $user1->setEmail($email1);
134
        $user2->setEmail($email2);
135
        $user3->setEmail($email3);
136
137
        $this->em->persist($user1);
138
        $this->em->persist($user2);
139
        $this->em->persist($user3);
140
141
        $this->em->persist($email1);
142
        $this->em->persist($email2);
143
        $this->em->persist($email3);
144
145
        $this->em->flush();
146
        $this->em->clear();
147
148
        return [$user1, $user2, $user3];
149
    }
150
151
    public function buildUser($name, $username, $status, $address)
152
    {
153
        $user = new CmsUser();
154
        $user->name     = $name;
155
        $user->username = $username;
156
        $user->status   = $status;
157
        $user->setAddress($address);
158
159
        $this->em->persist($user);
160
        $this->em->flush();
161
162
        return $user;
163
    }
164
165
    public function buildAddress($country, $city, $street, $zip)
166
    {
167
        $address = new CmsAddress();
168
        $address->country = $country;
169
        $address->city    = $city;
170
        $address->street  = $street;
171
        $address->zip     = $zip;
172
173
        $this->em->persist($address);
174
        $this->em->flush();
175
176
        return $address;
177
    }
178
179 View Code Duplication
    public function testBasicFind()
180
    {
181
        $user1Id = $this->loadFixture();
182
        $repos = $this->em->getRepository(CmsUser::class);
183
184
        $user = $repos->find($user1Id);
185
        self::assertInstanceOf(CmsUser::class,$user);
186
        self::assertEquals('Roman', $user->name);
187
        self::assertEquals('freak', $user->status);
188
    }
189
190 View Code Duplication
    public function testFindByField()
191
    {
192
        $user1Id = $this->loadFixture();
0 ignored issues
show
Unused Code introduced by
$user1Id 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...
193
        $repos = $this->em->getRepository(CmsUser::class);
194
195
        $users = $repos->findBy(['status' => 'dev']);
196
        self::assertEquals(2, count($users));
197
        self::assertInstanceOf(CmsUser::class,$users[0]);
198
        self::assertEquals('Guilherme', $users[0]->name);
199
        self::assertEquals('dev', $users[0]->status);
200
    }
201
202 View Code Duplication
    public function testFindByAssociationWithIntegerAsParameter()
203
    {
204
        $address1 = $this->buildAddress('Germany', 'Berlim', 'Foo st.', '123456');
205
        $user1    = $this->buildUser('Benjamin', 'beberlei', 'dev', $address1);
206
207
        $address2 = $this->buildAddress('Brazil', 'São Paulo', 'Bar st.', '654321');
208
        $user2    = $this->buildUser('Guilherme', 'guilhermeblanco', 'freak', $address2);
209
210
        $address3 = $this->buildAddress('USA', 'Nashville', 'Woo st.', '321654');
211
        $user3    = $this->buildUser('Jonathan', 'jwage', 'dev', $address3);
0 ignored issues
show
Unused Code introduced by
$user3 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...
212
213
        unset($address1);
214
        unset($address2);
215
        unset($address3);
216
217
        $this->em->clear();
218
219
        $repository = $this->em->getRepository(CmsAddress::class);
220
        $addresses  = $repository->findBy(['user' => [$user1->getId(), $user2->getId()]]);
221
222
        self::assertEquals(2, count($addresses));
223
        self::assertInstanceOf(CmsAddress::class,$addresses[0]);
224
    }
225
226 View Code Duplication
    public function testFindByAssociationWithObjectAsParameter()
227
    {
228
        $address1 = $this->buildAddress('Germany', 'Berlim', 'Foo st.', '123456');
229
        $user1    = $this->buildUser('Benjamin', 'beberlei', 'dev', $address1);
230
231
        $address2 = $this->buildAddress('Brazil', 'São Paulo', 'Bar st.', '654321');
232
        $user2    = $this->buildUser('Guilherme', 'guilhermeblanco', 'freak', $address2);
233
234
        $address3 = $this->buildAddress('USA', 'Nashville', 'Woo st.', '321654');
235
        $user3    = $this->buildUser('Jonathan', 'jwage', 'dev', $address3);
0 ignored issues
show
Unused Code introduced by
$user3 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...
236
237
        unset($address1);
238
        unset($address2);
239
        unset($address3);
240
241
        $this->em->clear();
242
243
        $repository = $this->em->getRepository(CmsAddress::class);
244
        $addresses  = $repository->findBy(['user' => [$user1, $user2]]);
245
246
        self::assertEquals(2, count($addresses));
247
        self::assertInstanceOf(CmsAddress::class,$addresses[0]);
248
    }
249
250 View Code Duplication
    public function testFindFieldByMagicCall()
251
    {
252
        $user1Id = $this->loadFixture();
0 ignored issues
show
Unused Code introduced by
$user1Id 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...
253
        $repos = $this->em->getRepository(CmsUser::class);
254
255
        $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()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
256
        self::assertEquals(2, count($users));
257
        self::assertInstanceOf(CmsUser::class,$users[0]);
258
        self::assertEquals('Guilherme', $users[0]->name);
259
        self::assertEquals('dev', $users[0]->status);
260
    }
261
262 View Code Duplication
    public function testFindAll()
263
    {
264
        $user1Id = $this->loadFixture();
0 ignored issues
show
Unused Code introduced by
$user1Id 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...
265
        $repos = $this->em->getRepository(CmsUser::class);
266
267
        $users = $repos->findAll();
268
        self::assertEquals(4, count($users));
269
    }
270
271
    public function testFindByAlias()
272
    {
273
        $user1Id = $this->loadFixture();
0 ignored issues
show
Unused Code introduced by
$user1Id 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...
274
        $repos = $this->em->getRepository(CmsUser::class);
0 ignored issues
show
Unused Code introduced by
$repos 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...
275
276
        $this->em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS');
277
278
        $repos = $this->em->getRepository('CMS:CmsUser');
279
280
        $users = $repos->findAll();
281
        self::assertEquals(4, count($users));
282
    }
283
284
    public function testCount()
285
    {
286
        $this->loadFixture();
287
        $repos = $this->em->getRepository(CmsUser::class);
288
289
        $userCount = $repos->count([]);
290
        self::assertSame(4, $userCount);
291
292
        $userCount = $repos->count(['status' => 'dev']);
293
        self::assertSame(2, $userCount);
294
295
        $userCount = $repos->count(['status' => 'nonexistent']);
296
        self::assertSame(0, $userCount);
297
    }
298
299
    public function testCountBy()
300
    {
301
        $this->loadFixture();
302
        $repos = $this->em->getRepository(CmsUser::class);
303
304
        $userCount = $repos->countByStatus('dev');
305
        self::assertSame(2, $userCount);
306
    }
307
308
    /**
309
     * @expectedException \Doctrine\ORM\ORMException
310
     */
311
    public function testExceptionIsThrownWhenCallingFindByWithoutParameter() {
312
        $this->em->getRepository(CmsUser::class)
0 ignored issues
show
Bug introduced by
The method findByStatus() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
313
                  ->findByStatus();
314
    }
315
316
    /**
317
     * @expectedException \Doctrine\ORM\ORMException
318
     */
319
    public function testExceptionIsThrownWhenUsingInvalidFieldName() {
320
        $this->em->getRepository(CmsUser::class)
0 ignored issues
show
Bug introduced by
The method findByThisFieldDoesNotExist() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
321
                  ->findByThisFieldDoesNotExist('testvalue');
322
    }
323
324
    /**
325
     * @group locking
326
     * @group DDC-178
327
     */
328
    public function testPessimisticReadLockWithoutTransaction_ThrowsException()
329
    {
330
        $this->expectException(TransactionRequiredException::class);
331
332
        $this->em->getRepository(CmsUser::class)
333
                  ->find(1, LockMode::PESSIMISTIC_READ);
0 ignored issues
show
Unused Code introduced by
The call to ObjectRepository::find() has too many arguments starting with \Doctrine\DBAL\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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
334
    }
335
336
    /**
337
     * @group locking
338
     * @group DDC-178
339
     */
340
    public function testPessimisticWriteLockWithoutTransaction_ThrowsException()
341
    {
342
        $this->expectException(TransactionRequiredException::class);
343
344
        $this->em->getRepository(CmsUser::class)
345
                  ->find(1, LockMode::PESSIMISTIC_WRITE);
0 ignored issues
show
Unused Code introduced by
The call to ObjectRepository::find() has too many arguments starting with \Doctrine\DBAL\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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
346
    }
347
348
    /**
349
     * @group locking
350
     * @group DDC-178
351
     */
352
    public function testOptimisticLockUnversionedEntity_ThrowsException()
353
    {
354
        $this->expectException(OptimisticLockException::class);
355
356
        $this->em->getRepository(CmsUser::class)
357
                  ->find(1, LockMode::OPTIMISTIC);
0 ignored issues
show
Unused Code introduced by
The call to ObjectRepository::find() has too many arguments starting with \Doctrine\DBAL\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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
358
    }
359
360
    /**
361
     * @group locking
362
     * @group DDC-178
363
     */
364
    public function testIdentityMappedOptimisticLockUnversionedEntity_ThrowsException()
365
    {
366
        $user = new CmsUser;
367
        $user->name = 'Roman';
368
        $user->username = 'romanb';
369
        $user->status = 'freak';
370
        $this->em->persist($user);
371
        $this->em->flush();
372
373
        $userId = $user->id;
374
375
        $this->em->find(CmsUser::class, $userId);
376
377
        $this->expectException(OptimisticLockException::class);
378
379
        $this->em->find(CmsUser::class, $userId, LockMode::OPTIMISTIC);
0 ignored issues
show
Unused Code introduced by
The call to EntityManagerInterface::find() has too many arguments starting with \Doctrine\DBAL\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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
380
    }
381
382
    /**
383
     * @group DDC-819
384
     */
385 View Code Duplication
    public function testFindMagicCallByNullValue()
386
    {
387
        $this->loadFixture();
388
389
        $repos = $this->em->getRepository(CmsUser::class);
390
391
        $users = $repos->findByStatus(null);
0 ignored issues
show
Bug introduced by
The method findByStatus() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
392
        self::assertEquals(1, count($users));
393
    }
394
395
    /**
396
     * @group DDC-819
397
     */
398
    public function testInvalidMagicCall()
399
    {
400
        $this->expectException(\BadMethodCallException::class);
401
402
        $repos = $this->em->getRepository(CmsUser::class);
403
        $repos->foo();
404
    }
405
406
    /**
407
     * @group DDC-817
408
     */
409
    public function testFindByAssociationKey_ExceptionOnInverseSide()
410
    {
411
        list($userId, $addressId) = $this->loadAssociatedFixture();
0 ignored issues
show
Unused Code introduced by
The assignment to $userId is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
412
        $repos = $this->em->getRepository(CmsUser::class);
413
414
        $this->expectException(ORMException::class);
415
        $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.");
416
417
        $user = $repos->findBy(['address' => $addressId]);
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...
418
    }
419
420
    /**
421
     * @group DDC-817
422
     */
423 View Code Duplication
    public function testFindOneByAssociationKey()
424
    {
425
        list($userId, $addressId) = $this->loadAssociatedFixture();
426
        $repos = $this->em->getRepository(CmsAddress::class);
427
        $address = $repos->findOneBy(['user' => $userId]);
428
429
        self::assertInstanceOf(CmsAddress::class, $address);
430
        self::assertEquals($addressId, $address->id);
431
    }
432
433
    /**
434
     * @group DDC-1241
435
     */
436
    public function testFindOneByOrderBy()
437
    {
438
    	$this->loadFixture();
439
440
    	$repos = $this->em->getRepository(CmsUser::class);
441
    	$userAsc = $repos->findOneBy([], ["username" => "ASC"]);
0 ignored issues
show
Unused Code introduced by
The call to ObjectRepository::findOneBy() has too many arguments starting with array('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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
442
    	$userDesc = $repos->findOneBy([], ["username" => "DESC"]);
0 ignored issues
show
Unused Code introduced by
The call to ObjectRepository::findOneBy() has too many arguments starting with array('username' => 'DESC').

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
443
444
    	self::assertNotSame($userAsc, $userDesc);
445
    }
446
447
    /**
448
     * @group DDC-817
449
     */
450 View Code Duplication
    public function testFindByAssociationKey()
451
    {
452
        list($userId, $addressId) = $this->loadAssociatedFixture();
453
        $repos = $this->em->getRepository(CmsAddress::class);
454
        $addresses = $repos->findBy(['user' => $userId]);
455
456
        self::assertContainsOnly(CmsAddress::class, $addresses);
457
        self::assertEquals(1, count($addresses));
458
        self::assertEquals($addressId, $addresses[0]->id);
459
    }
460
461
    /**
462
     * @group DDC-817
463
     */
464 View Code Duplication
    public function testFindAssociationByMagicCall()
465
    {
466
        list($userId, $addressId) = $this->loadAssociatedFixture();
467
        $repos = $this->em->getRepository(CmsAddress::class);
468
        $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()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
469
470
        self::assertContainsOnly(CmsAddress::class, $addresses);
471
        self::assertEquals(1, count($addresses));
472
        self::assertEquals($addressId, $addresses[0]->id);
473
    }
474
475
    /**
476
     * @group DDC-817
477
     */
478
    public function testFindOneAssociationByMagicCall()
479
    {
480
        list($userId, $addressId) = $this->loadAssociatedFixture();
481
        $repos = $this->em->getRepository(CmsAddress::class);
482
        $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()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
483
484
        self::assertInstanceOf(CmsAddress::class, $address);
485
        self::assertEquals($addressId, $address->id);
486
    }
487
488
    public function testValidNamedQueryRetrieval()
489
    {
490
        $repos = $this->em->getRepository(CmsUser::class);
491
492
        $query = $repos->createNamedQuery('all');
493
494
        self::assertInstanceOf(Query::class, $query);
495
        self::assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u', $query->getDQL());
496
    }
497
498
    public function testInvalidNamedQueryRetrieval()
499
    {
500
        $repos = $this->em->getRepository(CmsUser::class);
501
502
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
503
504
        $repos->createNamedQuery('invalidNamedQuery');
505
    }
506
507
    /**
508
     * @group DDC-1087
509
     */
510
    public function testIsNullCriteriaDoesNotGenerateAParameter()
511
    {
512
        $repos = $this->em->getRepository(CmsUser::class);
513
        $users = $repos->findBy(['status' => null, 'username' => 'romanb']);
0 ignored issues
show
Unused Code introduced by
$users 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...
514
515
        $params = $this->sqlLoggerStack->queries[$this->sqlLoggerStack->currentQuery]['params'];
516
        self::assertEquals(1, count($params), "Should only execute with one parameter.");
517
        self::assertEquals(['romanb'], $params);
518
    }
519
520 View Code Duplication
    public function testIsNullCriteria()
521
    {
522
        $this->loadFixture();
523
524
        $repos = $this->em->getRepository(CmsUser::class);
525
526
        $users = $repos->findBy(['status' => null]);
527
        self::assertEquals(1, count($users));
528
    }
529
530
    /**
531
     * @group DDC-1094
532
     */
533
    public function testFindByLimitOffset()
534
    {
535
        $this->loadFixture();
536
537
        $repos = $this->em->getRepository(CmsUser::class);
538
539
        $users1 = $repos->findBy([], null, 1, 0);
540
        $users2 = $repos->findBy([], null, 1, 1);
541
542
        self::assertEquals(4, count($repos->findBy([])));
543
        self::assertEquals(1, count($users1));
544
        self::assertEquals(1, count($users2));
545
        self::assertNotSame($users1[0], $users2[0]);
546
    }
547
548
    /**
549
     * @group DDC-1094
550
     */
551
    public function testFindByOrderBy()
552
    {
553
        $this->loadFixture();
554
555
        $repos = $this->em->getRepository(CmsUser::class);
556
        $usersAsc = $repos->findBy([], ["username" => "ASC"]);
557
        $usersDesc = $repos->findBy([], ["username" => "DESC"]);
558
559
        self::assertEquals(4, count($usersAsc), "Pre-condition: only four users in fixture");
560
        self::assertEquals(4, count($usersDesc), "Pre-condition: only four users in fixture");
561
        self::assertSame($usersAsc[0], $usersDesc[3]);
562
        self::assertSame($usersAsc[3], $usersDesc[0]);
563
    }
564
565
    /**
566
     * @group DDC-1376
567
     */
568
    public function testFindByOrderByAssociation()
569
    {
570
        $this->loadFixtureUserEmail();
571
572
        $repository = $this->em->getRepository(CmsUser::class);
573
        $resultAsc  = $repository->findBy([], ['email' => 'ASC']);
574
        $resultDesc = $repository->findBy([], ['email' => 'DESC']);
575
576
        self::assertCount(3, $resultAsc);
577
        self::assertCount(3, $resultDesc);
578
579
        self::assertEquals($resultAsc[0]->getEmail()->getId(), $resultDesc[2]->getEmail()->getId());
580
        self::assertEquals($resultAsc[2]->getEmail()->getId(), $resultDesc[0]->getEmail()->getId());
581
    }
582
583
    /**
584
     * @group DDC-1426
585
     */
586
    public function testFindFieldByMagicCallOrderBy()
587
    {
588
        $this->loadFixture();
589
        $repos = $this->em->getRepository(CmsUser::class);
590
591
        $usersAsc = $repos->findByStatus('dev', ['username' => "ASC"]);
0 ignored issues
show
Bug introduced by
The method findByStatus() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
592
        $usersDesc = $repos->findByStatus('dev', ['username' => "DESC"]);
0 ignored issues
show
Bug introduced by
The method findByStatus() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
593
594
        self::assertEquals(2, count($usersAsc));
595
        self::assertEquals(2, count($usersDesc));
596
597
        self::assertInstanceOf(CmsUser::class,$usersAsc[0]);
598
        self::assertEquals('Alexander', $usersAsc[0]->name);
599
        self::assertEquals('dev', $usersAsc[0]->status);
600
601
        self::assertSame($usersAsc[0], $usersDesc[1]);
602
        self::assertSame($usersAsc[1], $usersDesc[0]);
603
    }
604
605
    /**
606
     * @group DDC-1426
607
     */
608
    public function testFindFieldByMagicCallLimitOffset()
609
    {
610
        $this->loadFixture();
611
        $repos = $this->em->getRepository(CmsUser::class);
612
613
        $users1 = $repos->findByStatus('dev', [], 1, 0);
0 ignored issues
show
Bug introduced by
The method findByStatus() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
614
        $users2 = $repos->findByStatus('dev', [], 1, 1);
0 ignored issues
show
Bug introduced by
The method findByStatus() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
615
616
        self::assertEquals(1, count($users1));
617
        self::assertEquals(1, count($users2));
618
        self::assertNotSame($users1[0], $users2[0]);
619
    }
620
621
    /**
622
     * @group DDC-753
623
     */
624
    public function testDefaultRepositoryClassName()
625
    {
626
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), EntityRepository::class);
627
        $this->em->getConfiguration()->setDefaultRepositoryClassName(DDC753DefaultRepository::class);
628
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), DDC753DefaultRepository::class);
629
630
        $repos = $this->em->getRepository(DDC753EntityWithDefaultCustomRepository::class);
631
        self::assertInstanceOf(DDC753DefaultRepository::class, $repos);
632
        self::assertTrue($repos->isDefaultRepository());
633
634
635
        $repos = $this->em->getRepository(DDC753EntityWithCustomRepository::class);
636
        self::assertInstanceOf(DDC753CustomRepository::class, $repos);
637
        self::assertTrue($repos->isCustomRepository());
638
639
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), DDC753DefaultRepository::class);
640
        $this->em->getConfiguration()->setDefaultRepositoryClassName(EntityRepository::class);
641
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), EntityRepository::class);
642
643
    }
644
645
    /**
646
     * @group DDC-753
647
     * @expectedException Doctrine\ORM\ORMException
648
     * @expectedExceptionMessage Invalid repository class 'Doctrine\Tests\Models\DDC753\DDC753InvalidRepository'. It must be a Doctrine\Common\Persistence\ObjectRepository.
649
     */
650
    public function testSetDefaultRepositoryInvalidClassError()
651
    {
652
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), EntityRepository::class);
653
        $this->em->getConfiguration()->setDefaultRepositoryClassName(DDC753InvalidRepository::class);
654
    }
655
656
    /**
657
     * @group DDC-3257
658
     */
659
    public function testSingleRepositoryInstanceForDifferentEntityAliases()
660
    {
661
        $config = $this->em->getConfiguration();
662
663
        $config->addEntityNamespace('Aliased', 'Doctrine\Tests\Models\CMS');
664
        $config->addEntityNamespace('AliasedAgain', 'Doctrine\Tests\Models\CMS');
665
666
        $repository = $this->em->getRepository(CmsUser::class);
667
668
        self::assertSame($repository, $this->em->getRepository('Aliased:CmsUser'));
669
        self::assertSame($repository, $this->em->getRepository('AliasedAgain:CmsUser'));
670
    }
671
672
    /**
673
     * @group DDC-3257
674
     */
675
    public function testCanRetrieveRepositoryFromClassNameWithLeadingBackslash()
676
    {
677
        self::assertSame(
678
            $this->em->getRepository('\\' . CmsUser::class),
679
            $this->em->getRepository(CmsUser::class)
680
        );
681
    }
682
683
    /**
684
     * @group DDC-1376
685
     *
686
     * @expectedException Doctrine\ORM\ORMException
687
     * @expectedExceptionMessage You cannot search for the association field 'Doctrine\Tests\Models\CMS\CmsUser#address', because it is the inverse side of an association.
688
     */
689
    public function testInvalidOrderByAssociation()
690
    {
691
        $this->em->getRepository(CmsUser::class)
692
            ->findBy(['status' => 'test'], ['address' => 'ASC']);
693
    }
694
695
    /**
696
     * @group DDC-1500
697
     */
698 View Code Duplication
    public function testInvalidOrientation()
699
    {
700
        $this->expectException(ORMException::class);
701
        $this->expectExceptionMessage('Invalid order by orientation specified for Doctrine\Tests\Models\CMS\CmsUser#username');
702
703
        $repo = $this->em->getRepository(CmsUser::class);
704
        $repo->findBy(['status' => 'test'], ['username' => 'INVALID']);
705
    }
706
707
    /**
708
     * @group DDC-1713
709
     */
710
    public function testFindByAssociationArray()
711
    {
712
        $repo = $this->em->getRepository(CmsAddress::class);
713
        $data = $repo->findBy(['user' => [1, 2, 3]]);
0 ignored issues
show
Unused Code introduced by
$data 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...
714
715
        $query = array_pop($this->sqlLoggerStack->queries);
716
        self::assertEquals([1,2,3], $query['params'][0]);
717
        self::assertEquals(Connection::PARAM_INT_ARRAY, $query['types'][0]);
718
    }
719
720
    /**
721
     * @group DDC-1637
722
     */
723 View Code Duplication
    public function testMatchingEmptyCriteria()
724
    {
725
        $this->loadFixture();
726
727
        $repository = $this->em->getRepository(CmsUser::class);
728
        $users = $repository->matching(new Criteria());
729
730
        self::assertEquals(4, count($users));
731
    }
732
733
    /**
734
     * @group DDC-1637
735
     */
736
    public function testMatchingCriteriaEqComparison()
737
    {
738
        $this->loadFixture();
739
740
        $repository = $this->em->getRepository(CmsUser::class);
741
        $users = $repository->matching(new Criteria(
742
            Criteria::expr()->eq('username', 'beberlei')
743
        ));
744
745
        self::assertEquals(1, count($users));
746
    }
747
748
    /**
749
     * @group DDC-1637
750
     */
751 View Code Duplication
    public function testMatchingCriteriaNeqComparison()
752
    {
753
        $this->loadFixture();
754
755
        $repository = $this->em->getRepository(CmsUser::class);
756
        $users = $repository->matching(new Criteria(
757
            Criteria::expr()->neq('username', 'beberlei')
758
        ));
759
760
        self::assertEquals(3, count($users));
761
    }
762
763
    /**
764
     * @group DDC-1637
765
     */
766 View Code Duplication
    public function testMatchingCriteriaInComparison()
767
    {
768
        $this->loadFixture();
769
770
        $repository = $this->em->getRepository(CmsUser::class);
771
        $users = $repository->matching(new Criteria(
772
            Criteria::expr()->in('username', ['beberlei', 'gblanco'])
773
        ));
774
775
        self::assertEquals(2, count($users));
776
    }
777
778
    /**
779
     * @group DDC-1637
780
     */
781 View Code Duplication
    public function testMatchingCriteriaNotInComparison()
782
    {
783
        $this->loadFixture();
784
785
        $repository = $this->em->getRepository(CmsUser::class);
786
        $users = $repository->matching(new Criteria(
787
            Criteria::expr()->notIn('username', ['beberlei', 'gblanco', 'asm89'])
788
        ));
789
790
        self::assertEquals(1, count($users));
791
    }
792
793
    /**
794
     * @group DDC-1637
795
     */
796
    public function testMatchingCriteriaLtComparison()
797
    {
798
        $firstUserId = $this->loadFixture();
799
800
        $repository = $this->em->getRepository(CmsUser::class);
801
        $users = $repository->matching(new Criteria(
802
            Criteria::expr()->lt('id', $firstUserId + 1)
803
        ));
804
805
        self::assertEquals(1, count($users));
806
    }
807
808
    /**
809
     * @group DDC-1637
810
     */
811
    public function testMatchingCriteriaLeComparison()
812
    {
813
        $firstUserId = $this->loadFixture();
814
815
        $repository = $this->em->getRepository(CmsUser::class);
816
        $users = $repository->matching(new Criteria(
817
            Criteria::expr()->lte('id', $firstUserId + 1)
818
        ));
819
820
        self::assertEquals(2, count($users));
821
    }
822
823
    /**
824
     * @group DDC-1637
825
     */
826
    public function testMatchingCriteriaGtComparison()
827
    {
828
        $firstUserId = $this->loadFixture();
829
830
        $repository = $this->em->getRepository(CmsUser::class);
831
        $users = $repository->matching(new Criteria(
832
            Criteria::expr()->gt('id', $firstUserId)
833
        ));
834
835
        self::assertEquals(3, count($users));
836
    }
837
838
    /**
839
     * @group DDC-1637
840
     */
841
    public function testMatchingCriteriaGteComparison()
842
    {
843
        $firstUserId = $this->loadFixture();
844
845
        $repository = $this->em->getRepository(CmsUser::class);
846
        $users = $repository->matching(new Criteria(
847
            Criteria::expr()->gte('id', $firstUserId)
848
        ));
849
850
        self::assertEquals(4, count($users));
851
    }
852
853
    /**
854
     * @group DDC-2430
855
     */
856 View Code Duplication
    public function testMatchingCriteriaAssocationByObjectInMemory()
857
    {
858
        list($userId, $addressId) = $this->loadAssociatedFixture();
0 ignored issues
show
Unused Code introduced by
The assignment to $addressId is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
859
860
        $user = $this->em->find(CmsUser::class, $userId);
861
862
        $criteria = new Criteria(
863
            Criteria::expr()->eq('user', $user)
864
        );
865
866
        $repository = $this->em->getRepository(CmsAddress::class);
867
        $addresses = $repository->matching($criteria);
868
869
        self::assertEquals(1, count($addresses));
870
871
        $addresses = new ArrayCollection($repository->findAll());
872
873
        self::assertEquals(1, count($addresses->matching($criteria)));
874
    }
875
876
    /**
877
     * @group DDC-2430
878
     */
879 View Code Duplication
    public function testMatchingCriteriaAssocationInWithArray()
880
    {
881
        list($userId, $addressId) = $this->loadAssociatedFixture();
0 ignored issues
show
Unused Code introduced by
The assignment to $addressId is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
882
883
        $user = $this->em->find(CmsUser::class, $userId);
884
885
        $criteria = new Criteria(
886
            Criteria::expr()->in('user', [$user])
887
        );
888
889
        $repository = $this->em->getRepository(CmsAddress::class);
890
        $addresses = $repository->matching($criteria);
891
892
        self::assertEquals(1, count($addresses));
893
894
        $addresses = new ArrayCollection($repository->findAll());
895
896
        self::assertEquals(1, count($addresses->matching($criteria)));
897
    }
898
899
    public function testMatchingCriteriaContainsComparison()
900
    {
901
        $this->loadFixture();
902
903
        $repository = $this->em->getRepository(CmsUser::class);
904
905
        $users = $repository->matching(new Criteria(Criteria::expr()->contains('name', 'Foobar')));
906
        self::assertEquals(0, count($users));
907
908
        $users = $repository->matching(new Criteria(Criteria::expr()->contains('name', 'Rom')));
909
        self::assertEquals(1, count($users));
910
911
        $users = $repository->matching(new Criteria(Criteria::expr()->contains('status', 'dev')));
912
        self::assertEquals(2, count($users));
913
    }
914
915 View Code Duplication
    public function testMatchingCriteriaStartsWithComparison()
916
    {
917
        $this->loadFixture();
918
919
        $repository = $this->em->getRepository(CmsUser::class);
920
921
        $users = $repository->matching(new Criteria(Criteria::expr()->startsWith('name', 'Foo')));
922
        self::assertCount(0, $users);
923
924
        $users = $repository->matching(new Criteria(Criteria::expr()->startsWith('name', 'R')));
925
        self::assertCount(1, $users);
926
927
        $users = $repository->matching(new Criteria(Criteria::expr()->startsWith('status', 'de')));
928
        self::assertCount(2, $users);
929
    }
930
931 View Code Duplication
    public function testMatchingCriteriaEndsWithComparison()
932
    {
933
        $this->loadFixture();
934
935
        $repository = $this->em->getRepository(CmsUser::class);
936
937
        $users = $repository->matching(new Criteria(Criteria::expr()->endsWith('name', 'foo')));
938
        self::assertCount(0, $users);
939
940
        $users = $repository->matching(new Criteria(Criteria::expr()->endsWith('name', 'oman')));
941
        self::assertCount(1, $users);
942
943
        $users = $repository->matching(new Criteria(Criteria::expr()->endsWith('status', 'ev')));
944
        self::assertCount(2, $users);
945
    }
946
947
    /**
948
     * @group DDC-2478
949
     */
950
    public function testMatchingCriteriaNullAssocComparison()
951
    {
952
        $fixtures       = $this->loadFixtureUserEmail();
953
        $user           = $this->em->merge($fixtures[0]);
954
        $repository     = $this->em->getRepository(CmsUser::class);
955
        $criteriaIsNull = Criteria::create()->where(Criteria::expr()->isNull('email'));
956
        $criteriaEqNull = Criteria::create()->where(Criteria::expr()->eq('email', null));
957
958
        $user->setEmail(null);
959
        $this->em->persist($user);
960
        $this->em->flush();
961
        $this->em->clear();
962
963
        $usersIsNull = $repository->matching($criteriaIsNull);
964
        $usersEqNull = $repository->matching($criteriaEqNull);
965
966
        self::assertCount(1, $usersIsNull);
967
        self::assertCount(1, $usersEqNull);
968
969
        self::assertInstanceOf(CmsUser::class, $usersIsNull[0]);
970
        self::assertInstanceOf(CmsUser::class, $usersEqNull[0]);
971
972
        self::assertNull($usersIsNull[0]->getEmail());
973
        self::assertNull($usersEqNull[0]->getEmail());
974
    }
975
976
    /**
977
     * @group DDC-2055
978
     */
979
    public function testCreateResultSetMappingBuilder()
980
    {
981
        $repository = $this->em->getRepository(CmsUser::class);
982
        $rsm = $repository->createResultSetMappingBuilder('u');
983
984
        self::assertInstanceOf(Query\ResultSetMappingBuilder::class, $rsm);
985
        self::assertEquals(['u' => CmsUser::class], $rsm->aliasMap);
986
    }
987
988
    /**
989
     * @group DDC-3045
990
     */
991 View Code Duplication
    public function testFindByFieldInjectionPrevented()
992
    {
993
        $this->expectException(ORMException::class);
994
        $this->expectExceptionMessage('Unrecognized field: ');
995
996
        $repository = $this->em->getRepository(CmsUser::class);
997
        $repository->findBy(['username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1' => 'test']);
998
    }
999
1000
    /**
1001
     * @group DDC-3045
1002
     */
1003 View Code Duplication
    public function testFindOneByFieldInjectionPrevented()
1004
    {
1005
        $this->expectException(ORMException::class);
1006
        $this->expectExceptionMessage('Unrecognized field: ');
1007
1008
        $repository = $this->em->getRepository(CmsUser::class);
1009
        $repository->findOneBy(['username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1' => 'test']);
1010
    }
1011
1012
    /**
1013
     * @group DDC-3045
1014
     */
1015
    public function testMatchingInjectionPrevented()
1016
    {
1017
        $this->expectException(ORMException::class);
1018
        $this->expectExceptionMessage('Unrecognized field: ');
1019
1020
        $repository = $this->em->getRepository(CmsUser::class);
1021
        $result     = $repository->matching(new Criteria(
1022
            Criteria::expr()->eq('username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1', 'beberlei')
1023
        ));
1024
1025
        // Because repository returns a lazy collection, we call toArray to force initialization
1026
        $result->toArray();
1027
    }
1028
1029
    /**
1030
     * @group DDC-3045
1031
     */
1032 View Code Duplication
    public function testFindInjectionPrevented()
1033
    {
1034
        $this->expectException(ORMException::class);
1035
        $this->expectExceptionMessage('Unrecognized identifier fields: ');
1036
1037
        $repository = $this->em->getRepository(CmsUser::class);
1038
        $repository->find(['username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1' => 'test', 'id' => 1]);
1039
    }
1040
1041
    /**
1042
     * @group DDC-3056
1043
     */
1044 View Code Duplication
    public function testFindByNullValueInInCondition()
1045
    {
1046
        $user1 = new CmsUser();
1047
        $user2 = new CmsUser();
1048
1049
        $user1->username = 'ocramius';
1050
        $user1->name = 'Marco';
1051
        $user2->status = null;
1052
        $user2->username = 'deeky666';
1053
        $user2->name = 'Steve';
1054
        $user2->status = 'dbal maintainer';
1055
1056
        $this->em->persist($user1);
1057
        $this->em->persist($user2);
1058
        $this->em->flush();
1059
1060
        $users = $this->em->getRepository(CmsUser::class)->findBy(['status' => [null]]);
1061
1062
        self::assertCount(1, $users);
1063
        self::assertSame($user1, reset($users));
1064
    }
1065
1066
    /**
1067
     * @group DDC-3056
1068
     */
1069 View Code Duplication
    public function testFindByNullValueInMultipleInCriteriaValues()
1070
    {
1071
        $user1 = new CmsUser();
1072
        $user2 = new CmsUser();
1073
1074
        $user1->username = 'ocramius';
1075
        $user1->name = 'Marco';
1076
        $user2->status = null;
1077
        $user2->username = 'deeky666';
1078
        $user2->name = 'Steve';
1079
        $user2->status = 'dbal maintainer';
1080
1081
        $this->em->persist($user1);
1082
        $this->em->persist($user2);
1083
        $this->em->flush();
1084
1085
        $users = $this
1086
            ->em
1087
            ->getRepository(CmsUser::class)
1088
            ->findBy(['status' => ['foo', null]]);
1089
1090
        self::assertCount(1, $users);
1091
        self::assertSame($user1, reset($users));
1092
    }
1093
1094
    /**
1095
     * @group DDC-3056
1096
     */
1097
    public function testFindMultipleByNullValueInMultipleInCriteriaValues()
1098
    {
1099
        $user1 = new CmsUser();
1100
        $user2 = new CmsUser();
1101
1102
        $user1->username = 'ocramius';
1103
        $user1->name = 'Marco';
1104
        $user2->status = null;
1105
        $user2->username = 'deeky666';
1106
        $user2->name = 'Steve';
1107
        $user2->status = 'dbal maintainer';
1108
1109
        $this->em->persist($user1);
1110
        $this->em->persist($user2);
1111
        $this->em->flush();
1112
1113
        $users = $this
1114
            ->em
1115
            ->getRepository(CmsUser::class)
1116
            ->findBy(['status' => ['dbal maintainer', null]]);
1117
1118
        self::assertCount(2, $users);
1119
1120
        foreach ($users as $user) {
1121
            self::assertTrue(in_array($user, [$user1, $user2]));
1122
        }
1123
    }
1124
}
1125
1126