GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#182)
by joseph
21:51
created

itCanUseEntitiesInDql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 0
dl 0
loc 16
rs 9.8666
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Large\C\Entity\Repositories;
4
5
use Doctrine\Common\Collections\Collection;
6
use Doctrine\Common\Collections\Criteria;
7
use Doctrine\Common\Collections\Expr\Comparison;
8
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
9
use EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\AbstractEntityRepository;
10
use EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\RepositoryFactory;
11
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\EntitySaver;
12
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityDebugDumper;
13
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\TestEntityGenerator;
14
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\TestEntityGeneratorFactory;
15
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
16
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
17
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractLargeTest;
18
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractTest;
19
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\TestCodeGenerator;
20
21
/**
22
 * @see     https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#querying
23
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
24
 * @SuppressWarnings(PHPMD.ExcessivePublicCount)
25
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
26
 * @large
27
 * @covers  \EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\AbstractEntityRepository
28
 */
29
class AbstractEntityRepositoryLargeTest extends AbstractLargeTest
30
{
31
    public const WORK_DIR = AbstractTest::VAR_PATH . '/'
32
                            . self::TEST_TYPE_LARGE . '/AbstractEntityRepositoryLargeTest';
33
34
    private const PERSON_ENTITY_FQN = self::TEST_ENTITIES_ROOT_NAMESPACE . TestCodeGenerator::TEST_ENTITY_PERSON;
35
36
    private const NUM_ENTITIES_QUICK = 2;
37
38
    private const NUM_ENTITIES_FULL = 10;
39
40
    protected static $buildOnce = true;
41
42
    private $generatedEntities = [];
43
    /**
44
     * @var AbstractEntityRepository
45
     */
46
    private $repository;
47
    /**
48
     * @var TestEntityGenerator $entityGenerator
49
     */
50
    private $entityGenerator;
51
52
    public function setup()
53
    {
54
        parent::setUp();
55
        $this->generateTestCode();
56
        $this->setupCopiedWorkDirAndCreateDatabase();
57
        $this->repository      = $this->getRepository();
58
        $this->entityGenerator = $this->container->get(TestEntityGeneratorFactory::class)
59
                                                 ->createForEntityFqn($this->getCopiedFqn(self::PERSON_ENTITY_FQN));
60
        $this->generateAndSaveTestEntities();
61
    }
62
63
    protected function getRepository(): AbstractEntityRepository
64
    {
65
        return $this->container->get(RepositoryFactory::class)
66
                               ->getRepository($this->getCopiedFqn(self::PERSON_ENTITY_FQN));
67
    }
68
69
    protected function generateAndSaveTestEntities(): void
70
    {
71
        $this->generatedEntities = $this->entityGenerator->generateEntities(
72
            $this->isQuickTests() ? self::NUM_ENTITIES_QUICK : self::NUM_ENTITIES_FULL
73
        );
74
75
        $saver = new EntitySaver($this->getEntityManager());
76
        $saver->saveAll($this->generatedEntities);
77
    }
78
79
    /**
80
     * @test
81
     */
82
    public function itCanRunAllTheBasicMethods(): void
83
    {
84
        $this->find();
85
        $this->get();
86
        $this->findAll();
87
        $this->findBy();
88
        $this->findOneBy();
89
        $this->matching();
90
        $this->createQueryBuilder();
91
        $this->createResultSetMappingBuilder();
92
        $this->get();
93
        $this->getOneBy();
94
        $this->getClassName();
95
    }
96
97
    private function find(): void
98
    {
99
        $expected = $this->generatedEntities[array_rand($this->generatedEntities)];
100
        $actual   = $this->repository->find($expected->getId());
101
        self::assertSame($expected, $actual);
102
    }
103
104
    private function get(): void
105
    {
106
        $expected = $this->generatedEntities[array_rand($this->generatedEntities)];
107
        $actual   = $this->repository->get($expected->getId());
108
        self::assertSame($expected, $actual);
109
    }
110
111
    private function findAll(): void
112
    {
113
        $expected = $this->sortCollectionById($this->generatedEntities);
114
        $actual   = $this->sortCollectionById($this->repository->findAll());
115
        self::assertEquals($expected, $actual);
116
    }
117
118
    private function sortCollectionById(array $collection): array
119
    {
120
        $return = [];
121
        foreach ($collection as $item) {
122
            $return[(string)$item->getId()] = $item;
123
        }
124
        ksort($return);
125
126
        return $return;
127
    }
128
129
    private function findBy(): void
130
    {
131
        foreach (MappingHelper::COMMON_TYPES as $property) {
132
            $entity   = current($this->generatedEntities);
133
            $getter   = $this->getGetterForType($property);
134
            $criteria = [$property => $entity->$getter()];
135
            $actual   = $this->repository->findBy($criteria);
136
            self::assertTrue($this->arrayContainsEntity($entity, $actual));
137
        }
138
    }
139
140
    protected function getGetterForType(string $type): string
141
    {
142
        $ucType = ucfirst($type);
143
        $getter = "get$ucType";
144
        if (MappingHelper::TYPE_BOOLEAN === $type) {
145
            $getter = "is$ucType";
146
        }
147
148
        return $getter;
149
    }
150
151
    protected function arrayContainsEntity(EntityInterface $expectedEntity, array $array): bool
152
    {
153
        foreach ($array as $entity) {
154
            if ($entity->getId() === $expectedEntity->getId()) {
155
                return true;
156
            }
157
        }
158
159
        return false;
160
    }
161
162
    private function findOneBy(): void
163
    {
164
        foreach (MappingHelper::COMMON_TYPES as $property) {
165
            $entity   = current($this->generatedEntities);
166
            $getter   = $this->getGetterForType($property);
167
            $value    = $entity->$getter();
168
            $criteria = [
169
                $property => $value,
170
                'id'      => $entity->getId(),
171
            ];
172
            $actual   = $this->repository->findOneBy($criteria);
173
            self::assertEquals(
174
                $entity,
175
                $actual,
176
                'Failed finding one expected entity (ID' . $entity->getId() . ') with $criteria: '
177
                . "\n" . var_export($criteria, true)
178
                . "\n and \$actual: "
179
                . "\n" . (new EntityDebugDumper())->dump($actual, $this->getEntityManager())
0 ignored issues
show
Bug introduced by
It seems like $actual can also be of type null; however, parameter $entity of EdmondsCommerce\Doctrine...tityDebugDumper::dump() does only seem to accept EdmondsCommerce\Doctrine...erfaces\EntityInterface, maybe add an additional type check? ( Ignorable by Annotation )

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

179
                . "\n" . (new EntityDebugDumper())->dump(/** @scrutinizer ignore-type */ $actual, $this->getEntityManager())
Loading history...
180
            );
181
        }
182
    }
183
184
    private function matching(): void
185
    {
186
        foreach (MappingHelper::COMMON_TYPES as $property) {
187
            $entity   = current($this->generatedEntities);
188
            $getter   = $this->getGetterForType($property);
189
            $value    = $entity->$getter();
190
            $criteria = new Criteria();
191
            $criteria->where(new Comparison($property, '=', $value));
192
//            $criteria->andWhere(new Comparison('id', '=', $entity->getId()));
193
            $actual = $this->repository->matching($criteria);
194
            self::assertTrue($this->collectionContainsEntity($entity, $actual),
195
                             "Failed finding entity by criteria $property = $value");
196
        }
197
    }
198
199
    protected function collectionContainsEntity(EntityInterface $expectedEntity, Collection $collection): bool
200
    {
201
        foreach ($collection->getIterator() as $entity) {
202
            if ($entity->getId()->toString() === $expectedEntity->getId()->toString()) {
203
                return true;
204
            }
205
        }
206
207
        return false;
208
    }
209
210
    private function createQueryBuilder(): void
211
    {
212
        $this->repository->createQueryBuilder('foo');
213
        self::assertTrue(true);
214
    }
215
216
    private function createResultSetMappingBuilder(): void
217
    {
218
        $this->repository->createResultSetMappingBuilder('foo');
219
        self::assertTrue(true);
220
    }
221
222
    private function getOneBy(): void
223
    {
224
        $entity   = current($this->generatedEntities);
225
        $getter   = $this->getGetterForType(MappingHelper::TYPE_STRING);
226
        $value    = $entity->$getter();
227
        $criteria = [
228
            MappingHelper::TYPE_STRING => $value,
229
            'id'                       => $entity->getId(),
230
        ];
231
        $actual   = $this->repository->findOneBy($criteria);
232
        self::assertEquals(
233
            $entity,
234
            $actual,
235
            'Failed finding one expected entity (ID' . $entity->getId() . ') with $criteria: '
236
            . "\n" . var_export($criteria, true)
237
            . "\n and \$actual: "
238
            . "\n" . (new EntityDebugDumper())->dump($actual, $this->getEntityManager())
0 ignored issues
show
Bug introduced by
It seems like $actual can also be of type null; however, parameter $entity of EdmondsCommerce\Doctrine...tityDebugDumper::dump() does only seem to accept EdmondsCommerce\Doctrine...erfaces\EntityInterface, maybe add an additional type check? ( Ignorable by Annotation )

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

238
            . "\n" . (new EntityDebugDumper())->dump(/** @scrutinizer ignore-type */ $actual, $this->getEntityManager())
Loading history...
239
        );
240
    }
241
242
    /**
243
     * @test
244
     */
245
    public function itCanUseEntitiesInDql(): void
246
    {
247
        $this->addAssocEntities();
248
        $queryBuilder = $this->repository->createQueryBuilder('fetch');
249
        $queryBuilder->where('fetch.attributesAddress IS NOT NULL');
250
251
        $person      = $queryBuilder->getQuery()->execute()[0];
252
        $address     = $person->getAttributesAddress();
253
        $secondQuery = $this->repository->createQueryBuilder('second');
254
        $secondQuery->where('second.attributesAddress = :address');
255
        $secondQuery->setParameter('address', $address);
256
        $query        = $secondQuery->getQuery();
257
        $secondPerson = $query->execute();
258
        self::assertNotEmpty($secondPerson);
259
260
        self::assertSame($address->getId()->toString(), $secondPerson[0]->getAttributesAddress()->getId()->toString());
261
    }
262
263
    private function addAssocEntities(): void
264
    {
265
        foreach ($this->generatedEntities as $entity) {
266
            $this->entityGenerator->addAssociationEntities($entity);
267
        }
268
        $saver = new EntitySaver($this->getEntityManager());
269
        $saver->saveAll($this->generatedEntities);
270
    }
271
272
    /**
273
     * @test
274
     */
275
    public function getWillThrowAnExceptionIfNothingIsFound(): void
276
    {
277
        $this->expectException(DoctrineStaticMetaException::class);
278
        $this->repository->get(time());
279
    }
280
281
    /**
282
     * @test
283
     */
284
    public function getOneByWillThrowAnExceptionIfNothingIsFound(): void
285
    {
286
        $property = MappingHelper::TYPE_STRING;
287
        $criteria = [$property => 'not-a-real-vaule'];
288
        $this->expectException(\RuntimeException::class);
289
        $this->repository->getOneBy($criteria);
290
    }
291
292
    /**
293
     * @test
294
     */
295
    public function getClassName(): void
296
    {
297
        self::assertSame(
298
            ltrim($this->getCopiedFqn(self::PERSON_ENTITY_FQN), '\\'),
299
            $this->repository->getClassName()
300
        );
301
    }
302
303
    /**
304
     * @test
305
     */
306
    public function createNamedQuery(): void
307
    {
308
        $this->markTestIncomplete(
309
            'Need to add a named query for a test entity somehow in the meta data before we can test this'
310
        );
311
        $this->repository->createNamedQuery('foo');
312
        self::assertTrue(true);
313
    }
314
315
    /**
316
     * @test
317
     */
318
    public function clear(): void
319
    {
320
        $this->repository->clear();
321
        $map = $this->getEntityManager()->getUnitOfWork()->getIdentityMap();
322
        self::assertSame(
323
            [],
324
            $map[ltrim($this->getCopiedFqn(self::PERSON_ENTITY_FQN), '\\')]
325
        );
326
    }
327
328
    /**
329
     */
330
    public function testCount(): void
331
    {
332
        self::assertSame(
333
            $this->isQuickTests() ? self::NUM_ENTITIES_QUICK : self::NUM_ENTITIES_FULL,
334
            $this->repository->count([])
335
        );
336
    }
337
338
    /**
339
     * @test
340
     */
341
    public function getRandomBy(): void
342
    {
343
        $criteria = [];
344
        $result   = $this->repository->getRandomBy($criteria);
345
        self::assertCount(1, $result);
346
        $result = $this->repository->getRandomBy($criteria, 2);
347
        self::assertCount(2, $result);
348
    }
349
350
    /**
351
     * @test
352
     */
353
    public function getRandomOneBy(): void
354
    {
355
        $criteria = [];
356
        $tries    = 0;
357
        $maxTries = 3;
358
        while ($tries++ < $maxTries) {
359
            $rand1 = $this->repository->getRandomOneBy($criteria);
360
            $rand2 = $this->repository->getRandomOneBy($criteria);
361
            if ($rand1 !== $rand2) {
362
                self::assertTrue(true);
363
364
                return;
365
            }
366
        }
367
        $this->fail('Failed pulling out two random entities that were not the same');
368
    }
369
}
370