Completed
Pull Request — 3.x (#937)
by Oleg
12:53
created

testGetIdentifierValuesWhenIdentifierIsValueObjectWithToStringMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 9.44
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\DoctrineORMAdminBundle\Tests\Model;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Doctrine\Common\Persistence\ObjectManager;
18
use Doctrine\DBAL\Connection;
19
use Doctrine\DBAL\DBALException;
20
use Doctrine\DBAL\Platforms\MySqlPlatform;
21
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
22
use Doctrine\DBAL\Types\Type;
23
use Doctrine\ORM\Configuration;
24
use Doctrine\ORM\EntityManager;
25
use Doctrine\ORM\Mapping\ClassMetadata;
26
use Doctrine\ORM\Mapping\ClassMetadataFactory;
27
use Doctrine\ORM\OptimisticLockException;
28
use Doctrine\ORM\Query;
29
use Doctrine\ORM\QueryBuilder;
30
use Doctrine\ORM\Version;
31
use PHPUnit\Framework\TestCase;
32
use Sonata\AdminBundle\Datagrid\Datagrid;
33
use Sonata\AdminBundle\Datagrid\DatagridInterface;
34
use Sonata\AdminBundle\Exception\LockException;
35
use Sonata\AdminBundle\Exception\ModelManagerException;
36
use Sonata\AdminBundle\Filter\FilterInterface;
37
use Sonata\DoctrineORMAdminBundle\Admin\FieldDescription;
38
use Sonata\DoctrineORMAdminBundle\Datagrid\OrderByToSelectWalker;
39
use Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery;
40
use Sonata\DoctrineORMAdminBundle\Model\ModelManager;
41
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\ProductIdType;
42
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\Uuid;
43
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\UuidBinaryType;
44
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\UuidType;
45
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\AbstractEntity;
46
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\AssociatedEntity;
47
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\ContainerEntity;
48
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Embeddable\EmbeddedEntity;
49
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Embeddable\SubEmbeddedEntity;
50
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Product;
51
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\ProductId;
52
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\ProtectedEntity;
53
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\SimpleEntity;
54
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\UuidBinaryEntity;
55
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\UuidEntity;
56
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\VersionedEntity;
57
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Util\NonIntegerIdentifierTestClass;
58
use Symfony\Bridge\Doctrine\RegistryInterface;
59
60
class ModelManagerTest extends TestCase
61
{
62
    public static function setUpBeforeClass(): void
63
    {
64
        if (!Type::hasType(UuidType::NAME)) {
65
            Type::addType(UuidType::NAME, UuidType::class);
66
        }
67
        if (!Type::hasType(UuidBinaryType::NAME)) {
68
            Type::addType(UuidBinaryType::NAME, UuidBinaryType::class);
69
        }
70
        if (!Type::hasType(ProductIdType::NAME)) {
71
            Type::addType(ProductIdType::NAME, ProductIdType::class);
72
        }
73
    }
74
75
    public function testGetIdentifierValuesWhenIdentifierIsValueObjectWithToStringMethod()
76
    {
77
        $entity = new UuidBinaryEntity(new Uuid('a7ef873a-e7b5-11e9-81b4-2a2ae2dbcce4'));
78
79
        $platform = $this->createMock(MySqlPlatform::class);
80
81
        $connection = $this->createMock(Connection::class);
82
        $connection->expects($this->any())->method('getDatabasePlatform')->willReturn($platform);
83
84
        $classMetadata = $this->createMock(ClassMetadata::class);
85
        $classMetadata->expects($this->any())->method('getIdentifierValues')->willReturn([$entity->getId()]);
86
        $classMetadata->expects($this->any())->method('getTypeOfField')->willReturn(UuidBinaryType::NAME);
87
88
        $classMetadataFactory = $this->createMock(ClassMetadataFactory::class);
89
        $classMetadataFactory->expects($this->any())->method('getMetadataFor')->willReturn($classMetadata);
90
91
        $entityManager = $this->createMock(EntityManager::class);
92
        $entityManager->expects($this->any())->method('getMetadataFactory')->willReturn($classMetadataFactory);
93
        $entityManager->expects($this->any())->method('getConnection')->willReturn($connection);
94
95
        $registry = $this->createMock(RegistryInterface::class);
96
        $registry->expects($this->any())->method('getManagerForClass')->willReturn($entityManager);
97
98
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
99
100
        $this->assertEquals(
101
            ['a7ef873a-e7b5-11e9-81b4-2a2ae2dbcce4'],
102
            $manager->getIdentifierValues($entity)
103
        );
104
    }
105
106
    public function testSortParameters(): void
107
    {
108
        $registry = $this->createMock(RegistryInterface::class);
109
110
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
111
112
        $datagrid1 = $this->createMock(Datagrid::class);
113
        $datagrid2 = $this->createMock(Datagrid::class);
114
115
        $field1 = new FieldDescription();
116
        $field1->setName('field1');
117
118
        $field2 = new FieldDescription();
119
        $field2->setName('field2');
120
121
        $field3 = new FieldDescription();
122
        $field3->setName('field3');
123
        $field3->setOption('sortable', 'field3sortBy');
124
125
        $datagrid1
126
            ->expects($this->any())
127
            ->method('getValues')
128
            ->willReturn([
129
                '_sort_by' => $field1,
130
                '_sort_order' => 'ASC',
131
            ]);
132
133
        $datagrid2
134
            ->expects($this->any())
135
            ->method('getValues')
136
            ->willReturn([
137
                '_sort_by' => $field3,
138
                '_sort_order' => 'ASC',
139
            ]);
140
141
        $parameters = $manager->getSortParameters($field1, $datagrid1);
0 ignored issues
show
Documentation introduced by
$datagrid1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Sonata\AdminBundl...grid\DatagridInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
142
143
        $this->assertSame('DESC', $parameters['filter']['_sort_order']);
144
        $this->assertSame('field1', $parameters['filter']['_sort_by']);
145
146
        $parameters = $manager->getSortParameters($field2, $datagrid1);
0 ignored issues
show
Documentation introduced by
$datagrid1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Sonata\AdminBundl...grid\DatagridInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
147
148
        $this->assertSame('ASC', $parameters['filter']['_sort_order']);
149
        $this->assertSame('field2', $parameters['filter']['_sort_by']);
150
151
        $parameters = $manager->getSortParameters($field3, $datagrid1);
0 ignored issues
show
Documentation introduced by
$datagrid1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Sonata\AdminBundl...grid\DatagridInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
152
153
        $this->assertSame('ASC', $parameters['filter']['_sort_order']);
154
        $this->assertSame('field3sortBy', $parameters['filter']['_sort_by']);
155
156
        $parameters = $manager->getSortParameters($field3, $datagrid2);
0 ignored issues
show
Documentation introduced by
$datagrid2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Sonata\AdminBundl...grid\DatagridInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
157
158
        $this->assertSame('DESC', $parameters['filter']['_sort_order']);
159
        $this->assertSame('field3sortBy', $parameters['filter']['_sort_by']);
160
    }
161
162
    public function getVersionDataProvider()
163
    {
164
        return [
165
            [true],
166
            [false],
167
        ];
168
    }
169
170
    /**
171
     * @dataProvider getVersionDataProvider
172
     */
173
    public function testGetVersion($isVersioned): void
174
    {
175
        $object = new VersionedEntity();
176
177
        $modelManager = $this->getMockBuilder(ModelManager::class)
178
            ->disableOriginalConstructor()
179
            ->setMethods(['getMetadata'])
180
            ->getMock();
181
182
        $metadata = $this->getMetadata(\get_class($object), $isVersioned);
183
184
        $modelManager->expects($this->any())
185
            ->method('getMetadata')
186
            ->willReturn($metadata);
187
188
        if ($isVersioned) {
189
            $object->version = 123;
190
191
            $this->assertNotNull($modelManager->getLockVersion($object));
192
        } else {
193
            $this->assertNull($modelManager->getLockVersion($object));
194
        }
195
    }
196
197
    public function lockDataProvider()
198
    {
199
        return [
200
            [true,  false],
201
            [true,  true],
202
            [false, false],
203
        ];
204
    }
205
206
    /**
207
     * @dataProvider lockDataProvider
208
     */
209
    public function testLock($isVersioned, $expectsException): void
210
    {
211
        $object = new VersionedEntity();
212
213
        $em = $this->getMockBuilder(EntityManager::class)
214
            ->disableOriginalConstructor()
215
            ->setMethods(['lock'])
216
            ->getMock();
217
218
        $modelManager = $this->getMockBuilder(ModelManager::class)
219
            ->disableOriginalConstructor()
220
            ->setMethods(['getMetadata', 'getEntityManager'])
221
            ->getMock();
222
223
        $modelManager->expects($this->any())
224
            ->method('getEntityManager')
225
            ->willReturn($em);
226
227
        $metadata = $this->getMetadata(\get_class($object), $isVersioned);
228
229
        $modelManager->expects($this->any())
230
            ->method('getMetadata')
231
            ->willReturn($metadata);
232
233
        $em->expects($isVersioned ? $this->once() : $this->never())
234
            ->method('lock');
235
236
        if ($expectsException) {
237
            $em->expects($this->once())
238
                ->method('lock')
239
                ->will($this->throwException(OptimisticLockException::lockFailed($object)));
240
241
            $this->expectException(LockException::class);
242
        }
243
244
        $modelManager->lock($object, 123);
245
    }
246
247
    public function testGetParentMetadataForProperty(): void
248
    {
249
        if (version_compare(Version::VERSION, '2.5') < 0) {
250
            $this->markTestSkipped('Test for embeddables needs to run on Doctrine >= 2.5');
251
252
            return;
253
        }
254
255
        $containerEntityClass = ContainerEntity::class;
256
        $associatedEntityClass = AssociatedEntity::class;
257
        $embeddedEntityClass = EmbeddedEntity::class;
258
        $modelManagerClass = ModelManager::class;
259
260
        $em = $this->createMock(EntityManager::class);
261
262
        /** @var \PHPUnit_Framework_MockObject_MockObject|ModelManager $modelManager */
263
        $modelManager = $this->getMockBuilder($modelManagerClass)
264
            ->disableOriginalConstructor()
265
            ->setMethods(['getMetadata', 'getEntityManager'])
266
            ->getMock();
267
268
        $modelManager->expects($this->any())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Sonata\DoctrineORMAdminBundle\Model\ModelManager.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
269
            ->method('getEntityManager')
270
            ->willReturn($em);
271
272
        $containerEntityMetadata = $this->getMetadataForContainerEntity();
273
        $associatedEntityMetadata = $this->getMetadataForAssociatedEntity();
274
        $embeddedEntityMetadata = $this->getMetadataForEmbeddedEntity();
275
276
        $modelManager->expects($this->any())->method('getMetadata')
277
            ->willReturnMap(
278
279
                    [
280
                        [$containerEntityClass, $containerEntityMetadata],
281
                        [$embeddedEntityClass, $embeddedEntityMetadata],
282
                        [$associatedEntityClass, $associatedEntityMetadata],
283
                    ]
284
285
            );
286
287
        /** @var ClassMetadata $metadata */
288
        list($metadata, $lastPropertyName) = $modelManager
0 ignored issues
show
Bug introduced by
The method getParentMetadataForProperty does only exist in Sonata\DoctrineORMAdminBundle\Model\ModelManager, but not in PHPUnit_Framework_MockObject_MockObject.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
289
            ->getParentMetadataForProperty($containerEntityClass, 'plainField');
290
        $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'integer');
291
292
        list($metadata, $lastPropertyName) = $modelManager
293
            ->getParentMetadataForProperty($containerEntityClass, 'associatedEntity.plainField');
294
        $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'string');
295
296
        list($metadata, $lastPropertyName) = $modelManager
297
            ->getParentMetadataForProperty($containerEntityClass, 'embeddedEntity.plainField');
298
        $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean');
299
300
        list($metadata, $lastPropertyName) = $modelManager
301
            ->getParentMetadataForProperty($containerEntityClass, 'associatedEntity.embeddedEntity.plainField');
302
        $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean');
303
304
        list($metadata, $lastPropertyName) = $modelManager
305
            ->getParentMetadataForProperty(
306
                $containerEntityClass,
307
                'associatedEntity.embeddedEntity.subEmbeddedEntity.plainField'
308
            );
309
        $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean');
310
    }
311
312
    public function getMetadataForEmbeddedEntity()
313
    {
314
        $metadata = new ClassMetadata(EmbeddedEntity::class);
315
316
        $metadata->fieldMappings = [
317
            'plainField' => [
318
                'fieldName' => 'plainField',
319
                'columnName' => 'plainField',
320
                'type' => 'boolean',
321
            ],
322
        ];
323
324
        return $metadata;
325
    }
326
327
    public function getMetadataForSubEmbeddedEntity()
328
    {
329
        $metadata = new ClassMetadata(SubEmbeddedEntity::class);
330
331
        $metadata->fieldMappings = [
332
            'plainField' => [
333
                'fieldName' => 'plainField',
334
                'columnName' => 'plainField',
335
                'type' => 'boolean',
336
            ],
337
        ];
338
339
        return $metadata;
340
    }
341
342
    public function getMetadataForAssociatedEntity()
343
    {
344
        $embeddedEntityClass = EmbeddedEntity::class;
345
        $subEmbeddedEntityClass = SubEmbeddedEntity::class;
346
347
        $metadata = new ClassMetadata(AssociatedEntity::class);
348
349
        $metadata->fieldMappings = [
350
            'plainField' => [
351
                'fieldName' => 'plainField',
352
                'columnName' => 'plainField',
353
                'type' => 'string',
354
            ],
355
        ];
356
357
        $metadata->embeddedClasses['embeddedEntity'] = [
358
            'class' => $embeddedEntityClass,
359
            'columnPrefix' => 'embedded_entity_',
360
        ];
361
        $metadata->embeddedClasses['embeddedEntity.subEmbeddedEntity'] = [
362
            'class' => $subEmbeddedEntityClass,
363
            'columnPrefix' => 'embedded_entity_sub_embedded_entity_',
364
            'declaredField' => 'embeddedEntity',
365
            'originalField' => 'subEmbeddedEntity',
366
        ];
367
368
        $metadata->inlineEmbeddable('embeddedEntity', $this->getMetadataForEmbeddedEntity());
369
        $metadata->inlineEmbeddable('embeddedEntity.subEmbeddedEntity', $this->getMetadataForSubEmbeddedEntity());
370
371
        return $metadata;
372
    }
373
374
    public function getMetadataForContainerEntity()
375
    {
376
        $containerEntityClass = ContainerEntity::class;
377
        $associatedEntityClass = AssociatedEntity::class;
378
        $embeddedEntityClass = EmbeddedEntity::class;
379
        $subEmbeddedEntityClass = SubEmbeddedEntity::class;
380
381
        $metadata = new ClassMetadata($containerEntityClass);
382
383
        $metadata->fieldMappings = [
384
            'plainField' => [
385
                'fieldName' => 'plainField',
386
                'columnName' => 'plainField',
387
                'type' => 'integer',
388
            ],
389
        ];
390
391
        $metadata->associationMappings['associatedEntity'] = [
392
            'fieldName' => 'associatedEntity',
393
            'targetEntity' => $associatedEntityClass,
394
            'sourceEntity' => $containerEntityClass,
395
        ];
396
397
        $metadata->embeddedClasses['embeddedEntity'] = [
398
            'class' => $embeddedEntityClass,
399
            'columnPrefix' => 'embeddedEntity',
400
        ];
401
        $metadata->embeddedClasses['embeddedEntity.subEmbeddedEntity'] = [
402
            'class' => $subEmbeddedEntityClass,
403
            'columnPrefix' => 'embedded_entity_sub_embedded_entity_',
404
            'declaredField' => 'embeddedEntity',
405
            'originalField' => 'subEmbeddedEntity',
406
        ];
407
408
        $metadata->inlineEmbeddable('embeddedEntity', $this->getMetadataForEmbeddedEntity());
409
        $metadata->inlineEmbeddable('embeddedEntity.subEmbeddedEntity', $this->getMetadataForSubEmbeddedEntity());
410
411
        return $metadata;
412
    }
413
414
    public function testGetIdentifierValuesForIdInObjectTypeBinaryToStringSupport(): void
415
    {
416
        $uuid = new NonIntegerIdentifierTestClass('efbcfc4b-8c43-4d42-aa4c-d707e55151ac');
417
418
        $entity = new UuidEntity($uuid);
419
420
        $meta = $this->createMock(ClassMetadata::class);
421
        $meta->expects($this->any())
422
            ->method('getIdentifierValues')
423
            ->willReturn([$entity->getId()]);
424
        $meta->expects($this->any())
425
            ->method('getTypeOfField')
426
            ->willReturn(UuidBinaryType::NAME); //'uuid_binary'
427
428
        $mf = $this->createMock(ClassMetadataFactory::class);
429
        $mf->expects($this->any())
430
            ->method('getMetadataFor')
431
            ->willReturn($meta);
432
433
        $platform = $this->createMock(PostgreSqlPlatform::class);
434
        $platform->expects($this->any())
435
            ->method('hasDoctrineTypeMappingFor')
436
            ->with(UuidBinaryType::NAME)
437
            ->willReturn(true);
438
        $platform->expects($this->any())
439
            ->method('getDoctrineTypeMapping')
440
            ->with(UuidBinaryType::NAME)
441
            ->willReturn('binary');
442
443
        $conn = $this->createMock(Connection::class);
444
        $conn->expects($this->any())
445
            ->method('getDatabasePlatform')
446
            ->willReturn($platform);
447
448
        $em = $this->createMock(EntityManager::class);
449
        $em->expects($this->any())
450
            ->method('getMetadataFactory')
451
            ->willReturn($mf);
452
        $em->expects($this->any())
453
            ->method('getConnection')
454
            ->willReturn($conn);
455
456
        $registry = $this->createMock(RegistryInterface::class);
457
        $registry->expects($this->any())
458
            ->method('getManagerForClass')
459
            ->willReturn($em);
460
461
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
462
        $result = $manager->getIdentifierValues($entity);
463
464
        $this->assertSame($entity->getId()->toString(), $result[0]);
465
    }
466
467
    public function testNonIntegerIdentifierType(): void
468
    {
469
        $uuid = new NonIntegerIdentifierTestClass('efbcfc4b-8c43-4d42-aa4c-d707e55151ac');
470
        $entity = new UuidEntity($uuid);
471
472
        $meta = $this->createMock(ClassMetadata::class);
473
        $meta->expects($this->any())
474
            ->method('getIdentifierValues')
475
            ->willReturn([$entity->getId()]);
476
        $meta->expects($this->any())
477
            ->method('getTypeOfField')
478
            ->willReturn(UuidType::NAME);
479
480
        $mf = $this->createMock(ClassMetadataFactory::class);
481
        $mf->expects($this->any())
482
            ->method('getMetadataFor')
483
            ->willReturn($meta);
484
485
        $platform = $this->createMock(PostgreSqlPlatform::class);
486
        $platform->expects($this->any())
487
            ->method('hasDoctrineTypeMappingFor')
488
            ->with(UuidType::NAME)
489
            ->willReturn(false);
490
        $platform->expects($this->never())
491
            ->method('getDoctrineTypeMapping');
492
493
        $conn = $this->createMock(Connection::class);
494
        $conn->expects($this->any())
495
            ->method('getDatabasePlatform')
496
            ->willReturn($platform);
497
498
        $em = $this->createMock(EntityManager::class);
499
        $em->expects($this->any())
500
            ->method('getMetadataFactory')
501
            ->willReturn($mf);
502
        $em->expects($this->any())
503
            ->method('getConnection')
504
            ->willReturn($conn);
505
506
        $registry = $this->createMock(RegistryInterface::class);
507
        $registry->expects($this->any())
508
            ->method('getManagerForClass')
509
            ->willReturn($em);
510
511
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
512
        $result = $manager->getIdentifierValues($entity);
513
514
        $this->assertSame($entity->getId()->toString(), $result[0]);
515
    }
516
517
    public function testIntegerIdentifierType(): void
518
    {
519
        $id = new ProductId(12345);
520
        $entity = new Product($id, 'Some product');
521
522
        $meta = $this->createMock(ClassMetadata::class);
523
        $meta->expects($this->any())
524
            ->method('getIdentifierValues')
525
            ->willReturn([$entity->getId()]);
526
        $meta->expects($this->any())
527
            ->method('getTypeOfField')
528
            ->willReturn(ProductIdType::NAME);
529
530
        $mf = $this->createMock(ClassMetadataFactory::class);
531
        $mf->expects($this->any())
532
            ->method('getMetadataFor')
533
            ->willReturn($meta);
534
535
        $platform = $this->createMock(PostgreSqlPlatform::class);
536
        $platform->expects($this->any())
537
            ->method('hasDoctrineTypeMappingFor')
538
            ->with(ProductIdType::NAME)
539
            ->willReturn(false);
540
        $platform->expects($this->never())
541
            ->method('getDoctrineTypeMapping');
542
543
        $conn = $this->createMock(Connection::class);
544
        $conn->expects($this->any())
545
            ->method('getDatabasePlatform')
546
            ->willReturn($platform);
547
548
        $em = $this->createMock(EntityManager::class);
549
        $em->expects($this->any())
550
            ->method('getMetadataFactory')
551
            ->willReturn($mf);
552
        $em->expects($this->any())
553
            ->method('getConnection')
554
            ->willReturn($conn);
555
556
        $registry = $this->createMock(RegistryInterface::class);
557
        $registry->expects($this->any())
558
            ->method('getManagerForClass')
559
            ->willReturn($em);
560
561
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
562
        $result = $manager->getIdentifierValues($entity);
563
564
        $this->assertSame((string) $entity->getId()->getId(), $result[0]);
565
    }
566
567
    public function testAssociationIdentifierType(): void
568
    {
569
        $entity = new ContainerEntity(new AssociatedEntity(42, new EmbeddedEntity()), new EmbeddedEntity());
570
571
        $meta = $this->createMock(ClassMetadata::class);
572
        $meta->expects($this->any())
573
            ->method('getIdentifierValues')
574
            ->willReturn([$entity->getAssociatedEntity()->getPlainField()]);
575
        $meta->expects($this->any())
576
            ->method('getTypeOfField')
577
            ->willReturn(null);
578
579
        $mf = $this->createMock(ClassMetadataFactory::class);
580
        $mf->expects($this->any())
581
            ->method('getMetadataFor')
582
            ->willReturn($meta);
583
584
        $platform = $this->createMock(PostgreSqlPlatform::class);
585
        $platform->expects($this->never())
586
            ->method('hasDoctrineTypeMappingFor');
587
588
        $conn = $this->createMock(Connection::class);
589
        $conn->expects($this->any())
590
            ->method('getDatabasePlatform')
591
            ->willReturn($platform);
592
593
        $em = $this->createMock(EntityManager::class);
594
        $em->expects($this->any())
595
            ->method('getMetadataFactory')
596
            ->willReturn($mf);
597
        $em->expects($this->any())
598
            ->method('getConnection')
599
            ->willReturn($conn);
600
601
        $registry = $this->createMock(RegistryInterface::class);
602
        $registry->expects($this->any())
603
            ->method('getManagerForClass')
604
            ->willReturn($em);
605
606
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
607
        $result = $manager->getIdentifierValues($entity);
608
609
        $this->assertSame(42, $result[0]);
610
    }
611
612
    /**
613
     * [sortBy, sortOrder, isAddOrderBy].
614
     *
615
     * @return array
616
     */
617
    public function getSortableInDataSourceIteratorDataProvider()
618
    {
619
        return [
620
            [null, null, false],
621
            ['', 'ASC', false],
622
            ['field', 'ASC', true],
623
            ['field', null, true],
624
        ];
625
    }
626
627
    /**
628
     * @dataProvider getSortableInDataSourceIteratorDataProvider
629
     *
630
     * @param string|null $sortBy
631
     * @param string|null $sortOrder
632
     * @param bool        $isAddOrderBy
633
     */
634
    public function testSortableInDataSourceIterator($sortBy, $sortOrder, $isAddOrderBy): void
635
    {
636
        $datagrid = $this->getMockForAbstractClass(DatagridInterface::class);
637
        $configuration = $this->getMockBuilder(Configuration::class)->getMock();
638
        $configuration->expects($this->any())
639
            ->method('getDefaultQueryHints')
640
            ->willReturn([]);
641
642
        $em = $this->getMockBuilder(EntityManager::class)
643
            ->disableOriginalConstructor()
644
            ->getMock();
645
646
        $em->expects($this->any())
647
            ->method('getConfiguration')
648
            ->willReturn($configuration);
649
650
        $queryBuilder = $this->getMockBuilder(QueryBuilder::class)
651
            ->setConstructorArgs([$em])
652
            ->getMock();
653
        $query = new Query($em);
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
654
655
        $proxyQuery = $this->getMockBuilder(ProxyQuery::class)
656
            ->setConstructorArgs([$queryBuilder])
657
            ->setMethods(['getSortBy', 'getSortOrder', 'getRootAliases'])
658
            ->getMock();
659
660
        $proxyQuery->expects($this->any())
661
            ->method('getSortOrder')
662
            ->willReturn($sortOrder);
663
664
        $proxyQuery->expects($this->any())
665
            ->method('getSortBy')
666
            ->willReturn($sortBy);
667
668
        $queryBuilder->expects($isAddOrderBy ? $this->atLeastOnce() : $this->never())
669
            ->method('addOrderBy');
670
671
        $proxyQuery->expects($this->any())
672
            ->method('getRootAliases')
673
            ->willReturn(['a']);
674
675
        $queryBuilder->expects($this->any())
676
            ->method('getQuery')
677
            ->willReturn($query);
678
679
        $datagrid->expects($this->any())
680
            ->method('getQuery')
681
            ->willReturn($proxyQuery);
682
683
        $registry = $this->getMockBuilder(RegistryInterface::class)->getMock();
684
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
685
        $manager->getDataSourceIterator($datagrid, []);
0 ignored issues
show
Documentation introduced by
$datagrid is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Sonata\AdminBundl...grid\DatagridInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
686
687
        if ($isAddOrderBy) {
688
            $this->assertArrayHasKey($key = 'doctrine.customTreeWalkers', $hints = $query->getHints());
689
            $this->assertContains(OrderByToSelectWalker::class, $hints[$key]);
690
        }
691
    }
692
693
    public function testModelReverseTransform(): void
694
    {
695
        $class = SimpleEntity::class;
696
697
        $metadataFactory = $this->createMock(ClassMetadataFactory::class);
698
        $modelManager = $this->createMock(ObjectManager::class);
699
        $registry = $this->createMock(RegistryInterface::class);
700
701
        $classMetadata = new ClassMetadata($class);
702
        $classMetadata->reflClass = new \ReflectionClass($class);
703
704
        $modelManager->expects($this->once())
705
            ->method('getMetadataFactory')
706
            ->willReturn($metadataFactory);
707
        $metadataFactory->expects($this->once())
708
            ->method('getMetadataFor')
709
            ->with($class)
710
            ->willReturn($classMetadata);
711
        $registry->expects($this->once())
712
            ->method('getManagerForClass')
713
            ->with($class)
714
            ->willReturn($modelManager);
715
716
        $manager = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
717
        $this->assertInstanceOf($class, $object = $manager->modelReverseTransform(
718
            $class,
719
            [
720
                'schmeckles' => 42,
721
                'multi_word_property' => 'hello',
722
            ]
723
        ));
724
        $this->assertSame(42, $object->getSchmeckles());
725
        $this->assertSame('hello', $object->getMultiWordProperty());
726
    }
727
728
    public function testCollections(): void
729
    {
730
        $registry = $this->createMock(RegistryInterface::class);
731
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
732
733
        $collection = $model->getModelCollectionInstance('whyDoWeEvenHaveThisParameter');
734
        $this->assertInstanceOf(ArrayCollection::class, $collection);
735
736
        $item1 = 'item1';
737
        $item2 = 'item2';
738
        $model->collectionAddElement($collection, $item1);
0 ignored issues
show
Bug introduced by
It seems like $collection defined by $model->getModelCollecti...EvenHaveThisParameter') on line 733 can also be of type object<ArrayAccess>; however, Sonata\DoctrineORMAdminB...:collectionAddElement() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Documentation introduced by
$item1 is of type string, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
739
        $model->collectionAddElement($collection, $item2);
0 ignored issues
show
Documentation introduced by
$item2 is of type string, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
740
741
        $this->assertTrue($model->collectionHasElement($collection, $item1));
742
743
        $model->collectionRemoveElement($collection, $item1);
744
745
        $this->assertFalse($model->collectionHasElement($collection, $item1));
746
747
        $model->collectionClear($collection);
748
749
        $this->assertTrue($collection->isEmpty());
0 ignored issues
show
Bug introduced by
The method isEmpty cannot be called on $collection (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
750
    }
751
752
    public function testModelTransform(): void
753
    {
754
        $registry = $this->createMock(RegistryInterface::class);
755
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
756
757
        $result = $model->modelTransform('thisIsNotUsed', 'doWeNeedThisMethod');
0 ignored issues
show
Documentation introduced by
'doWeNeedThisMethod' is of type string, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
758
759
        $this->assertSame('doWeNeedThisMethod', $result);
760
    }
761
762
    public function testGetPaginationParameters(): void
763
    {
764
        $datagrid = $this->createMock(DatagridInterface::class);
765
        $filter = $this->createMock(FilterInterface::class);
766
        $registry = $this->createMock(RegistryInterface::class);
767
768
        $datagrid->expects($this->once())
769
            ->method('getValues')
770
            ->willReturn(['_sort_by' => $filter]);
771
772
        $filter->expects($this->once())
773
            ->method('getName')
774
            ->willReturn($name = 'test');
775
776
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
777
778
        $result = $model->getPaginationParameters($datagrid, $page = 5);
0 ignored issues
show
Documentation introduced by
$datagrid is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Sonata\AdminBundl...grid\DatagridInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
779
780
        $this->assertSame($page, $result['filter']['_page']);
781
        $this->assertSame($name, $result['filter']['_sort_by']);
782
    }
783
784
    public function testGetModelInstanceException(): void
785
    {
786
        $registry = $this->createMock(RegistryInterface::class);
787
788
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
789
790
        $this->expectException(\RuntimeException::class);
791
792
        $model->getModelInstance(AbstractEntity::class);
793
    }
794
795
    public function testGetModelInstanceForProtectedEntity(): void
796
    {
797
        $registry = $this->createMock(RegistryInterface::class);
798
799
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
800
801
        $this->assertInstanceOf(ProtectedEntity::class, $model->getModelInstance(ProtectedEntity::class));
802
    }
803
804
    public function testGetEntityManagerException(): void
805
    {
806
        $registry = $this->createMock(RegistryInterface::class);
807
808
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
809
810
        $this->expectException(\RuntimeException::class);
811
812
        $model->getEntityManager(VersionedEntity::class);
813
    }
814
815
    public function testGetNewFieldDescriptionInstanceException(): void
816
    {
817
        $registry = $this->createMock(RegistryInterface::class);
818
819
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
820
821
        $this->expectException(\RuntimeException::class);
822
823
        $model->getNewFieldDescriptionInstance(VersionedEntity::class, [], []);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
824
    }
825
826
    /**
827
     * @dataProvider createUpdateRemoveData
828
     */
829
    public function testCreate($exception): void
830
    {
831
        $registry = $this->createMock(RegistryInterface::class);
832
833
        $entityManger = $this->createMock(EntityManager::class);
834
835
        $registry->expects($this->once())
836
            ->method('getManagerForClass')
837
            ->willReturn($entityManger);
838
839
        $entityManger->expects($this->once())
840
            ->method('persist');
841
842
        $entityManger->expects($this->once())
843
            ->method('flush')
844
            ->willThrowException($exception);
845
846
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
847
848
        $this->expectException(ModelManagerException::class);
849
850
        $model->create(new VersionedEntity());
851
    }
852
853
    public function createUpdateRemoveData()
854
    {
855
        return [
856
            'PDOException' => [
857
                new \PDOException(),
858
            ],
859
            'DBALException' => [
860
                new DBALException(),
861
            ],
862
        ];
863
    }
864
865
    /**
866
     * @dataProvider createUpdateRemoveData
867
     */
868
    public function testUpdate($exception): void
869
    {
870
        $registry = $this->createMock(RegistryInterface::class);
871
872
        $entityManger = $this->createMock(EntityManager::class);
873
874
        $registry->expects($this->once())
875
            ->method('getManagerForClass')
876
            ->willReturn($entityManger);
877
878
        $entityManger->expects($this->once())
879
            ->method('persist');
880
881
        $entityManger->expects($this->once())
882
            ->method('flush')
883
            ->willThrowException($exception);
884
885
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
886
887
        $this->expectException(ModelManagerException::class);
888
889
        $model->update(new VersionedEntity());
890
    }
891
892
    /**
893
     * @dataProvider createUpdateRemoveData
894
     */
895
    public function testRemove($exception): void
896
    {
897
        $registry = $this->createMock(RegistryInterface::class);
898
899
        $entityManger = $this->createMock(EntityManager::class);
900
901
        $registry->expects($this->once())
902
            ->method('getManagerForClass')
903
            ->willReturn($entityManger);
904
905
        $entityManger->expects($this->once())
906
            ->method('remove');
907
908
        $entityManger->expects($this->once())
909
            ->method('flush')
910
            ->willThrowException($exception);
911
912
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
913
914
        $this->expectException(ModelManagerException::class);
915
916
        $model->delete(new VersionedEntity());
917
    }
918
919
    public function testFindBadId(): void
920
    {
921
        $registry = $this->createMock(RegistryInterface::class);
922
923
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
924
925
        $this->assertNull($model->find('notImportant', null));
926
    }
927
928
    public function testGetUrlsafeIdentifierException(): void
929
    {
930
        $registry = $this->createMock(RegistryInterface::class);
931
932
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
933
934
        $this->expectException(\RuntimeException::class);
935
936
        $model->getNormalizedIdentifier('test');
0 ignored issues
show
Documentation introduced by
'test' is of type string, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
937
    }
938
939
    public function testGetUrlsafeIdentifierNull(): void
940
    {
941
        $registry = $this->createMock(RegistryInterface::class);
942
943
        $model = new ModelManager($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
944
945
        $this->assertNull($model->getNormalizedIdentifier(null));
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
946
    }
947
948
    private function getMetadata($class, $isVersioned)
949
    {
950
        $metadata = new ClassMetadata($class);
951
952
        $metadata->isVersioned = $isVersioned;
953
954
        if ($isVersioned) {
955
            $versionField = 'version';
956
            $metadata->versionField = $versionField;
957
            $metadata->reflFields[$versionField] = new \ReflectionProperty($class, $versionField);
958
        }
959
960
        return $metadata;
961
    }
962
}
963