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 joseph
33:47
created

FixturesHelperTest::overrideCode()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 123
Code Lines 119

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 119
nc 1
nop 0
dl 0
loc 123
rs 8
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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