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 (#185)
by Ross
45:07
created

FixturesHelperTest.php$1 ➔ getAttributesEmails()   A

Complexity

Conditions 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Large\G\Entity\Testing\Fixtures;
4
5
use Doctrine\Common\Cache\FilesystemCache;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use EdmondsCommerce\DoctrineStaticMeta\Entity\DataTransferObjects\DtoFactory;
8
use EdmondsCommerce\DoctrineStaticMeta\Entity\Factory\EntityFactoryInterface;
9
use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Factories\UuidFactory;
10
use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Interfaces\String\EnumFieldInterface;
11
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\DataTransferObjectInterface;
12
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
13
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\EntitySaverFactory;
14
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader;
15
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\FixtureEntitiesModifierInterface;
16
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\FixturesHelper;
17
use EdmondsCommerce\DoctrineStaticMeta\Schema\Database;
18
use EdmondsCommerce\DoctrineStaticMeta\Schema\Schema;
19
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractLargeTest;
20
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractTest;
21
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\TestCodeGenerator;
22
use Ramsey\Uuid\UuidInterface;
23
24
/**
25
 * @covers \EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader
26
 * @covers \EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\FixturesHelper
27
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28
 * @SuppressWarnings(PHPMD.StaticAccess)
29
 */
30
class FixturesHelperTest extends AbstractLargeTest
31
{
32
    public const WORK_DIR = AbstractTest::VAR_PATH .
33
                            self::TEST_TYPE_LARGE .
34
                            '/FixturesTest';
35
36
    private const ENTITY_WITHOUT_MODIFIER = self::TEST_ENTITIES_ROOT_NAMESPACE .
37
                                            TestCodeGenerator::TEST_ENTITY_PERSON;
38
39
    private const ENTITY_WITH_MODIFIER = self::TEST_ENTITIES_ROOT_NAMESPACE .
40
                                         TestCodeGenerator::TEST_ENTITY_PERSON;
41
42
    protected static $buildOnce = true;
43
    /**
44
     * @var FixturesHelper
45
     */
46
    private $helper;
47
48
    public function setup(): void
49
    {
50
        parent::setUp();
51
        if (false === self::$built) {
52
            $this->getTestCodeGenerator()
53
                 ->copyTo(self::WORK_DIR, self::TEST_PROJECT_ROOT_NAMESPACE);
54
            $this->overrideCode();
55
            self::$built = true;
56
        }
57
        $this->setupCopiedWorkDirAndCreateDatabase();
58
        $this->recreateDtos();
59
        $cacheDir = $this->copiedWorkDir . '/cache';
60
        mkdir($cacheDir, 0777, true);
61
        $this->helper = new FixturesHelper(
62
            $this->getEntityManager(),
63
            $this->container->get(Database::class),
64
            $this->container->get(Schema::class),
65
            new FilesystemCache($cacheDir),
66
            $this->container->get(EntitySaverFactory::class),
67
            $this->getNamespaceHelper(),
68
            $this->getTestEntityGeneratorFactory(),
69
            $this->container
70
        );
71
    }
72
73
    private function overrideCode(): void
74
    {
75
        $personClass = <<<'PHP'
76
<?php declare(strict_types=1);
77
78
namespace My\Test\Project\Entities;
79
// phpcs:disable Generic.Files.LineLength.TooLong
80
81
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
82
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
83
use EdmondsCommerce\DoctrineStaticMeta\Entity as DSM;
84
use My\Test\Project\Entity\Fields\Traits\BooleanFieldTrait;
85
use My\Test\Project\Entity\Fields\Traits\DatetimeFieldTrait;
86
use My\Test\Project\Entity\Fields\Traits\DecimalFieldTrait;
87
use My\Test\Project\Entity\Fields\Traits\FloatFieldTrait;
88
use My\Test\Project\Entity\Fields\Traits\IntegerFieldTrait;
89
use My\Test\Project\Entity\Fields\Traits\JsonFieldTrait;
90
use My\Test\Project\Entity\Fields\Traits\StringFieldTrait;
91
use My\Test\Project\Entity\Fields\Traits\TextFieldTrait;
92
use My\Test\Project\Entity\Interfaces\PersonInterface;
93
use My\Test\Project\Entity\Relations\Attributes\Address\Traits\HasAttributesAddress\HasAttributesAddressUnidirectionalManyToOne;
94
use My\Test\Project\Entity\Relations\Attributes\Email\Traits\HasRequiredAttributesEmails\HasRequiredAttributesEmailsOneToMany;
95
use My\Test\Project\Entity\Relations\Company\Director\Traits\HasCompanyDirector\HasCompanyDirectorInverseOneToOne;
96
use My\Test\Project\Entity\Relations\Large\Relation\Traits\HasLargeRelation\HasLargeRelationInverseOneToOne;
97
98
// phpcs:enable
99
class Person implements 
100
    PersonInterface
101
{
102
    /**
103
     * DSM Traits 
104
     */
105
    use DSM\Traits\UsesPHPMetaDataTrait;
106
    use DSM\Traits\ValidatedEntityTrait;
107
    use DSM\Traits\ImplementNotifyChangeTrackingPolicy;
108
    use DSM\Traits\AlwaysValidTrait;
109
110
    /**
111
     * Required Relations 
112
     */
113
    use HasRequiredAttributesEmailsOneToMany;
114
115
    /**
116
     * Relations 
117
     */
118
    use HasAttributesAddressUnidirectionalManyToOne;
119
    use HasCompanyDirectorInverseOneToOne;
120
    use HasLargeRelationInverseOneToOne;
121
122
    /**
123
     * DSM Fields 
124
     */
125
    use DSM\Fields\Traits\PrimaryKey\NonOrderedUuidFieldTrait;
126
127
    /**
128
     * Fields 
129
     */
130
    use StringFieldTrait;
131
    use DatetimeFieldTrait;
132
    use FloatFieldTrait;
133
    use DecimalFieldTrait;
134
    use IntegerFieldTrait;
135
    use TextFieldTrait;
136
    use BooleanFieldTrait;
137
    use JsonFieldTrait;
138
}
139
PHP;
140
        \ts\file_put_contents(self::WORK_DIR . '/src/Entities/Person.php', $personClass);
141
142
        $personFixture = <<<'PHP'
143
<?php declare(strict_types=1);
144
145
namespace My\Test\Project\Assets\Entity\Fixtures;
146
147
use Doctrine\Common\Collections\ArrayCollection;
148
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
149
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader;
150
use My\Test\Project\Assets\Entity\Fixtures\Attributes\EmailFixture;
151
152
class PersonFixture extends AbstractEntityFixtureLoader implements DependentFixtureInterface
153
{
154
    public const REFERENCE_PREFIX = 'Person_';
155
    
156
    public const BULK_AMOUNT_TO_GENERATE = 2;
157
158
    public function getDependencies(): array
159
    {
160
        return [EmailFixture::class];
161
    }
162
163
    protected function loadBulk(): array
164
    {
165
        $entities = parent::loadBulk();
166
        $num      = 0;
167
        foreach ($entities as $person) {
168
            $collection = new ArrayCollection();
169
            $collection->add($this->getReference(EmailFixture::REFERENCE_PREFIX . $num++));
170
            $person->setAttributesEmails($collection);
171
        }
172
173
        return $entities;
174
    }
175
}
176
PHP;
177
        \ts\file_put_contents(self::WORK_DIR . '/tests/Assets/Entity/Fixtures/PersonFixture.php', $personFixture);
178
179
        $emailFixture = <<<'PHP'
180
<?php declare(strict_types=1);
181
182
namespace My\Test\Project\Assets\Entity\Fixtures\Attributes;
183
184
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader;
185
186
class EmailFixture extends AbstractEntityFixtureLoader
187
{
188
    public const REFERENCE_PREFIX = 'Email_';
189
    public const BULK_AMOUNT_TO_GENERATE = 2;
190
}
191
192
PHP;
193
        \ts\file_put_contents(self::WORK_DIR . '/tests/Assets/Entity/Fixtures/Attributes/EmailFixture.php',
194
                              $emailFixture);
195
    }
196
197
    /**
198
     * @test
199
     * @large
200
     */
201
    public function itLoadsAllTheFixturesWithRandomDataByDefault(): array
202
    {
203
        $this->helper->setCacheKey(__CLASS__ . '_unmodified');
204
        $fixture = $this->getUnmodifiedFixture();
205
        $this->helper->addFixture($fixture);
206
        $this->helper->createDb();
207
        $entityFqn   = $this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER);
208
        $actual      = $this->getRepositoryFactory()
209
                            ->getRepository($entityFqn)
210
                            ->findAll();
211
        $actualCount = count($actual);
212
        self::assertSame($fixture::BULK_AMOUNT_TO_GENERATE, $actualCount);
213
214
        return $actual;
215
    }
216
217
    private function getUnmodifiedFixture(): AbstractEntityFixtureLoader
218
    {
219
        return $this->getFixture($this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER));
220
    }
221
222
    private function getFixture(
223
        string $entityFqn,
224
        ?FixtureEntitiesModifierInterface $modifier = null
225
    ): AbstractEntityFixtureLoader {
226
        return $this->helper->createFixtureInstanceForEntityFqn($entityFqn, $modifier);
227
    }
228
229
    /**
230
     * @test
231
     * @large
232
     * @depends itLoadsAllTheFixturesWithRandomDataByDefault
233
     *
234
     * @param array $loadedFirstTime
235
     *
236
     * @return array
237
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
238
     * @throws \ReflectionException
239
     */
240
    public function itUsesTheCacheTheSecondTime(array $loadedFirstTime): array
241
    {
242
        $this->getFileSystem()
243
             ->mirror(
244
                 $this->copiedWorkDir .
245
                 '/../FixturesHelperTest_ItLoadsAllTheFixturesWithRandomDataByDefault_/cache',
246
                 $this->copiedWorkDir . '/cache'
247
             );
248
        $this->helper->setCacheKey(__CLASS__ . '_unmodified');
249
        $fixture = $this->getUnmodifiedFixture();
250
        $this->helper->addFixture($fixture);
251
        $this->helper->createDb();
252
        self::assertTrue($this->helper->isLoadedFromCache());
253
        /**
254
         * @var EntityInterface[] $loadedSecondTime
255
         */
256
        $loadedSecondTime = $this->getRepositoryFactory()
257
                                 ->getRepository($this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER))
258
                                 ->findAll();
259
        $actualCount      = count($loadedSecondTime);
260
        $expectedCount    = count($loadedFirstTime);
261
        self::assertSame($expectedCount, $actualCount);
262
        $first  = $this->getArrayKeyedByUuid($loadedFirstTime);
263
        $second = $this->getArrayKeyedByUuid($loadedSecondTime);
264
        foreach ($second as $secondId => $actualEntity) {
265
            self::assertArrayHasKey($secondId, $first, 'Failed finding UUID ' . $secondId . ' in first Entities');
266
            $expectedEntity = $first[$secondId];
267
            $expectedText   = $expectedEntity->getString();
268
            $actualText     = $actualEntity->getString();
269
            self::assertEquals($expectedText, $actualText, 'Cached Faker data does not match');
270
        }
271
272
        return $loadedSecondTime;
273
    }
274
275
    /**
276
     * @param array $entities
277
     *
278
     * @return EntityInterface[]
279
     * @return EntityInterface[]
280
     */
281
    private function getArrayKeyedByUuid(array $entities): array
282
    {
283
        $return = [];
284
        foreach ($entities as $entity) {
285
            $return[$entity->getId()->toString()] = $entity;
286
        }
287
288
        return $return;
289
    }
290
291
    /**
292
     * @test
293
     * @large
294
     * @depends itUsesTheCacheTheSecondTime
295
     *
296
     * @param array $loadedSecondTime
297
     *
298
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
299
     * @throws \ReflectionException
300
     */
301
    public function itCanBeConfiguredNotToLoadFromTheCache(array $loadedSecondTime): void
302
    {
303
        $this->getFileSystem()
304
             ->mirror(
305
                 $this->copiedWorkDir .
306
                 '/../FixturesHelperTest_ItUsesTheCacheTheSecondTime_/cache',
307
                 $this->copiedWorkDir . '/cache'
308
             );
309
        $this->helper->setCacheKey(__CLASS__ . '_unmodified');
310
        $fixture = $this->getUnmodifiedFixture();
311
        $this->helper->setLoadFromCache(false);
312
        $this->helper->addFixture($fixture);
313
        $this->helper->createDb();
314
        self::assertFalse($this->helper->isLoadedFromCache());
315
        /**
316
         * @var EntityInterface[] $loadedThirdTime
317
         */
318
        $loadedThirdTime = $this->getRepositoryFactory()
319
                                ->getRepository($this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER))
320
                                ->findAll();
321
        $actualCount     = count($loadedThirdTime);
322
        $expectedCount   = count($loadedSecondTime);
323
        self::assertSame($expectedCount, $actualCount);
324
        foreach ($loadedThirdTime as $key => $actualEntity) {
325
            $loadedSecondTimeEntity = $loadedSecondTime[$key];
326
            $actualId               = $actualEntity->getId();
327
            $secondTimeEntityId     = $loadedSecondTimeEntity->getId();
328
            $secondTimeText         = $loadedSecondTimeEntity->getUniqueString();
329
            $actualText             = $actualEntity->getUniqueString();
0 ignored issues
show
Bug introduced by
The method getUniqueString() does not exist on EdmondsCommerce\Doctrine...erfaces\EntityInterface. ( Ignorable by Annotation )

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

329
            /** @scrutinizer ignore-call */ 
330
            $actualText             = $actualEntity->getUniqueString();

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...
330
            self::assertNotEquals($secondTimeEntityId, $actualId, 'Cached Entity ID matches, this should not happen');
331
            self::assertNotEquals($secondTimeText, $actualText, 'Cached Faker data matches, this should not happen');
332
        }
333
    }
334
335
    /**
336
     * @test
337
     * @large
338
     */
339
    public function itCanTakeAModifierToCustomiseTheFixtures(): void
340
    {
341
        $this->helper->setCacheKey(__CLASS__ . '_modified');
342
        $fixture = $this->getModifiedFixture();
343
        $this->helper->addFixture($fixture);
344
        $this->helper->createDb();
345
        /**
346
         * @var EntityInterface[] $actual
347
         */
348
        $actual      = $this->getRepositoryFactory()
349
                            ->getRepository($this->getCopiedFqn(self::ENTITY_WITH_MODIFIER))
350
                            ->findAll();
351
        $actualCount = count($actual);
352
        self::assertSame($fixture::BULK_AMOUNT_TO_GENERATE + 1, $actualCount);
353
        $foundStrings = [];
354
        foreach ($actual as $entity) {
355
            $foundStrings[$entity->getString()] = true;
0 ignored issues
show
Bug introduced by
The method getString() does not exist on EdmondsCommerce\Doctrine...erfaces\EntityInterface. ( Ignorable by Annotation )

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

355
            $foundStrings[$entity->/** @scrutinizer ignore-call */ getString()] = true;

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...
356
        }
357
        $overwrittenString = 'This has been overridden';
358
        $createdString = 'This has been created';
359
        self::assertArrayHasKey($overwrittenString, $foundStrings);
360
        self::assertArrayHasKey($createdString, $foundStrings);
361
    }
362
363
    private function getModifiedFixture(): AbstractEntityFixtureLoader
364
    {
365
        return $this->getFixture(
366
            $this->getCopiedFqn(self::ENTITY_WITH_MODIFIER),
367
            $this->getFixtureModifier()
368
        );
369
    }
370
371
    /**
372
     * @return FixtureEntitiesModifierInterface
373
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
374
     * @throws \ReflectionException
375
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
376
     */
377
    private function getFixtureModifier(): FixtureEntitiesModifierInterface
378
    {
379
380
        return new class(
381
            $this->getCopiedFqn(self::ENTITY_WITH_MODIFIER),
382
            $this->getEntityFactory(),
383
            $this->getEntityDtoFactory(),
384
            $this->getUuidFactory(),
385
            $this->getCopiedFqn(self::TEST_ENTITIES_ROOT_NAMESPACE . TestCodeGenerator::TEST_ENTITY_EMAIL)
386
        )
387
            implements FixtureEntitiesModifierInterface
388
        {
389
            /**
390
             * @var string
391
             */
392
            protected $entityFqn;
393
            /**
394
             * @var EntityFactoryInterface
395
             */
396
            protected $factory;
397
            /**
398
             * @var array|EntityInterface[]
399
             */
400
            private $entities;
401
            /**
402
             * @var DtoFactory
403
             */
404
            private $dtoFactory;
405
            /**
406
             * @var UuidFactory
407
             */
408
            private $uuidFactory;
409
            /**
410
             * @var string
411
             */
412
            private $emailFqn;
413
414
            public function __construct(
415
                string $entityFqn,
416
                EntityFactoryInterface $factory,
417
                DtoFactory $dtoFactory,
418
                UuidFactory $uuidFactory,
419
                string $emailFqn
420
            ) {
421
                $this->entityFqn   = $entityFqn;
422
                $this->factory     = $factory;
423
                $this->dtoFactory  = $dtoFactory;
424
                $this->uuidFactory = $uuidFactory;
425
                $this->emailFqn    = $emailFqn;
426
            }
427
428
            /**
429
             * Update the entities array by reference
430
             *
431
             * @param array $entities
432
             */
433
            public function modifyEntities(array &$entities): void
434
            {
435
                $this->entities = &$entities;
436
                $this->updateFirstEntity();
437
                $this->addAnotherEntity();
438
            }
439
440
            private function updateFirstEntity(): void
441
            {
442
                $firstEntity = current($this->entities);
443
                $firstEntity->update(
444
                    new class($this->entityFqn, $firstEntity->getId())
445
                        implements DataTransferObjectInterface
446
                    {
447
                        /**
448
                         * @var string
449
                         */
450
                        private static $entityFqn;
451
                        /**
452
                         * @var UuidInterface
453
                         */
454
                        private $id;
455
456
                        public function __construct(string $entityFqn, UuidInterface $id)
457
                        {
458
                            self::$entityFqn = $entityFqn;
459
                            $this->id        = $id;
460
                        }
461
462
                        public function getString(): string
463
                        {
464
                            return 'This has been overridden';
465
                        }
466
467
                        public static function getEntityFqn(): string
468
                        {
469
                            return self::$entityFqn;
470
                        }
471
472
                        public function getId(): UuidInterface
473
                        {
474
                            return $this->id;
475
                        }
476
                    }
477
                );
478
            }
479
480
            private function addAnotherEntity(): void
481
            {
482
                $address = $this->factory->create($this->emailFqn);
483
                $entity  = $this->factory->create(
484
                    $this->entityFqn,
485
                    new class($this->entityFqn, $this->uuidFactory, $address) implements DataTransferObjectInterface
486
                    {
487
                        /**
488
                         * @var string
489
                         */
490
                        private static $entityFqn;
491
                        /**
492
                         * @var \Ramsey\Uuid\UuidInterface
493
                         */
494
                        private $id;
495
                        /**
496
                         * @var EntityInterface
497
                         */
498
                        private $email;
499
500
                        public function __construct(string $entityFqn, UuidFactory $factory, EntityInterface $email)
501
                        {
502
                            self::$entityFqn = $entityFqn;
503
                            $this->id        = $factory->getOrderedTimeUuid();
504
                            $this->email     = $email;
505
                        }
506
507
                        public function getString(): string
508
                        {
509
                            return 'This has been created';
510
                        }
511
512
                        public static function getEntityFqn(): string
513
                        {
514
                            return self::$entityFqn;
515
                        }
516
517
                        public function getId(): UuidInterface
518
                        {
519
                            return $this->id;
520
                        }
521
522
                        public function getAttributesEmails(): ArrayCollection
523
                        {
524
                            $collection = new ArrayCollection();
525
                            $collection->add($this->email);
526
527
                            return $collection;
528
                        }
529
                    }
530
                );
531
532
                $this->entities[] = $entity;
533
            }
534
        };
535
    }
536
537
    /**
538
     * @test
539
     * @large
540
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
541
     * @throws \ReflectionException
542
     */
543
    public function fixturesUseTheCorrectFakerDataProviders(): void
544
    {
545
        $entityFqn = $this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER);
546
547
        $this->helper->setCacheKey(__CLASS__ . '_faker');
548
        $fixture = $this->getUnmodifiedFixture();
549
        $this->helper->addFixture($fixture);
550
        $this->helper->createDb();
551
        $actual = $this->getRepositoryFactory()
552
                       ->getRepository($entityFqn)
553
                       ->findAll();
554
        /**
555
         * @var EntityInterface $entity
556
         */
557
        foreach ($actual as $entity) {
558
            self::assertContains($entity->getEnum(), EnumFieldInterface::ENUM_OPTIONS);
559
        }
560
    }
561
}
562