Completed
Pull Request — master (#523)
by Jeroen
04:33
created

ModelManagerTest::testSortParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 55
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 55
rs 9.7692
cc 1
eloc 36
nc 1
nop 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
2
3
/*
4
 * This file is part of the Sonata package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\DoctrineORMAdminBundle\Tests\Model;
13
14
use Doctrine\DBAL\Types\Type;
15
use Doctrine\ORM\Mapping\ClassMetadata;
16
use Doctrine\ORM\OptimisticLockException;
17
use Doctrine\ORM\Version;
18
use Rhumsaa\Uuid\Doctrine\UuidType;
19
use Sonata\DoctrineORMAdminBundle\Admin\FieldDescription;
20
use Sonata\DoctrineORMAdminBundle\Model\ModelManager;
21
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\AssociatedEntity;
22
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\ContainerEntity;
23
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Embeddable\EmbeddedEntity;
24
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\UuidEntity;
25
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\VersionedEntity;
26
27
class ModelManagerTest extends \PHPUnit_Framework_TestCase
28
{
29
    public static function setUpBeforeClass()
30
    {
31
        if (!Type::hasType('uuid')) {
32
            Type::addType('uuid', 'Rhumsaa\Uuid\Doctrine\UuidType');
33
        }
34
    }
35
36
    public function testSortParameters()
37
    {
38
        $registry = $this->getMock('Symfony\Bridge\Doctrine\RegistryInterface');
39
40
        $manager  = new ModelManager($registry);
41
42
        $datagrid1 = $this->getMockBuilder('\Sonata\AdminBundle\Datagrid\Datagrid')->disableOriginalConstructor()->getMock();
43
        $datagrid2 = $this->getMockBuilder('\Sonata\AdminBundle\Datagrid\Datagrid')->disableOriginalConstructor()->getMock();
44
45
        $field1 = new FieldDescription();
46
        $field1->setName('field1');
47
48
        $field2 = new FieldDescription();
49
        $field2->setName('field2');
50
51
        $field3 = new FieldDescription();
52
        $field3->setName('field3');
53
        $field3->setOption('sortable', 'field3sortBy');
54
55
        $datagrid1
56
            ->expects($this->any())
57
            ->method('getValues')
58
            ->will($this->returnValue(array(
59
                '_sort_by'    => $field1,
60
                '_sort_order' => 'ASC',
61
            )));
62
63
        $datagrid2
64
            ->expects($this->any())
65
            ->method('getValues')
66
            ->will($this->returnValue(array(
67
                '_sort_by'    => $field3,
68
                '_sort_order' => 'ASC',
69
            )));
70
71
        $parameters = $manager->getSortParameters($field1, $datagrid1);
72
73
        $this->assertEquals('DESC', $parameters['filter']['_sort_order']);
74
        $this->assertEquals('field1', $parameters['filter']['_sort_by']);
75
76
        $parameters = $manager->getSortParameters($field2, $datagrid1);
77
78
        $this->assertEquals('ASC', $parameters['filter']['_sort_order']);
79
        $this->assertEquals('field2', $parameters['filter']['_sort_by']);
80
81
        $parameters = $manager->getSortParameters($field3, $datagrid1);
82
83
        $this->assertEquals('ASC', $parameters['filter']['_sort_order']);
84
        $this->assertEquals('field3sortBy', $parameters['filter']['_sort_by']);
85
86
        $parameters = $manager->getSortParameters($field3, $datagrid2);
87
88
        $this->assertEquals('DESC', $parameters['filter']['_sort_order']);
89
        $this->assertEquals('field3sortBy', $parameters['filter']['_sort_by']);
90
    }
91
92
    public function getVersionDataProvider()
93
    {
94
        return array(
95
            array(true),
96
            array(false),
97
        );
98
    }
99
100
    /**
101
     * @dataProvider getVersionDataProvider
102
     */
103
    public function testGetVersion($isVersioned)
104
    {
105
        $object = new VersionedEntity();
106
107
        $modelManager = $this->getMockBuilder('Sonata\DoctrineORMAdminBundle\Model\ModelManager')
108
            ->disableOriginalConstructor()
109
            ->setMethods(array('getMetadata'))
110
            ->getMock();
111
112
        $metadata = $this->getMetadata(get_class($object), $isVersioned);
113
114
        $modelManager->expects($this->any())
115
            ->method('getMetadata')
116
            ->will($this->returnValue($metadata));
117
118
        if ($isVersioned) {
119
            $object->version = 123;
120
121
            $this->assertNotNull($modelManager->getLockVersion($object));
122
        } else {
123
            $this->assertNull($modelManager->getLockVersion($object));
124
        }
125
    }
126
127
    public function lockDataProvider()
128
    {
129
        return array(
130
            array(true,  false),
131
            array(true,  true),
132
            array(false, false),
133
        );
134
    }
135
136
    /**
137
     * @dataProvider lockDataProvider
138
     */
139
    public function testLock($isVersioned, $expectsException)
140
    {
141
        $object = new VersionedEntity();
142
143
        $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
144
            ->disableOriginalConstructor()
145
            ->setMethods(array('lock'))
146
            ->getMock();
147
148
        $modelManager = $this->getMockBuilder('Sonata\DoctrineORMAdminBundle\Model\ModelManager')
149
            ->disableOriginalConstructor()
150
            ->setMethods(array('getMetadata', 'getEntityManager'))
151
            ->getMock();
152
153
        $modelManager->expects($this->any())
154
            ->method('getEntityManager')
155
            ->will($this->returnValue($em));
156
157
        $metadata = $this->getMetadata(get_class($object), $isVersioned);
158
159
        $modelManager->expects($this->any())
160
            ->method('getMetadata')
161
            ->will($this->returnValue($metadata));
162
163
        if ($expectsException) {
164
            $em->expects($this->once())
165
                ->method('lock')
166
                ->will($this->throwException(OptimisticLockException::lockFailed($object)));
167
168
            $this->setExpectedException('Sonata\AdminBundle\Exception\LockException');
169
        }
170
171
        $modelManager->lock($object, 123);
172
    }
173
174
    private function getMetadata($class, $isVersioned)
175
    {
176
        $metadata = new ClassMetadata($class);
177
178
        $metadata->isVersioned = $isVersioned;
179
180
        if ($isVersioned) {
181
            $versionField = 'version';
182
            $metadata->versionField = $versionField;
183
            $metadata->reflFields[$versionField] = new \ReflectionProperty($class, $versionField);
184
        }
185
186
        return $metadata;
187
    }
188
189
    public function testGetParentMetadataForProperty()
190
    {
191
        if (version_compare(Version::VERSION, '2.5') < 0) {
192
            $this->markTestSkipped('Test for embeddables needs to run on Doctrine >= 2.5');
193
194
            return;
195
        }
196
197
        $containerEntityClass = 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\ContainerEntity';
198
        $associatedEntityClass = 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\AssociatedEntity';
199
        $embeddedEntityClass = 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Embeddable\EmbeddedEntity';
200
        $modelManagerClass = 'Sonata\DoctrineORMAdminBundle\Model\ModelManager';
201
202
        $object = new ContainerEntity(new AssociatedEntity(), new EmbeddedEntity());
0 ignored issues
show
Unused Code introduced by
$object is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
203
204
        $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
205
            ->disableOriginalConstructor()
206
            ->getMock();
207
208
        /** @var \PHPUnit_Framework_MockObject_MockObject|ModelManager $modelManager */
209
        $modelManager = $this->getMockBuilder($modelManagerClass)
210
            ->disableOriginalConstructor()
211
            ->setMethods(array('getMetadata', 'getEntityManager'))
212
            ->getMock();
213
214
        $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...
215
            ->method('getEntityManager')
216
            ->will($this->returnValue($em));
217
218
        $containerEntityMetadata = $this->getMetadataForContainerEntity();
219
        $associatedEntityMetadata = $this->getMetadataForAssociatedEntity();
220
        $embeddedEntityMetadata = $this->getMetadataForEmbeddedEntity();
221
222
        $modelManager->expects($this->any())->method('getMetadata')
223
            ->will(
224
                $this->returnValueMap(
225
                    array(
226
                        array($containerEntityClass, $containerEntityMetadata),
227
                        array($embeddedEntityClass, $embeddedEntityMetadata),
228
                        array($associatedEntityClass, $associatedEntityMetadata),
229
                    )
230
                )
231
            );
232
233
        /** @var ClassMetadata $metadata */
234
        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...
235
            ->getParentMetadataForProperty($containerEntityClass, 'plainField');
236
        $this->assertEquals($metadata->fieldMappings[$lastPropertyName]['type'], 'integer');
237
238
        list($metadata, $lastPropertyName) = $modelManager
239
            ->getParentMetadataForProperty($containerEntityClass, 'associatedEntity.plainField');
240
        $this->assertEquals($metadata->fieldMappings[$lastPropertyName]['type'], 'string');
241
242
        list($metadata, $lastPropertyName) = $modelManager
243
            ->getParentMetadataForProperty($containerEntityClass, 'embeddedEntity.plainField');
244
        $this->assertEquals($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean');
245
    }
246
247
    public function getMetadataForEmbeddedEntity()
248
    {
249
        $metadata = new ClassMetadata('Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Embeddable\EmbeddedEntity');
250
251
        $metadata->fieldMappings = array(
252
            'plainField' => array(
253
                'fieldName'  => 'plainField',
254
                'columnName' => 'plainField',
255
                'type'       => 'boolean',
256
            ),
257
        );
258
259
        return $metadata;
260
    }
261
262
    public function getMetadataForAssociatedEntity()
263
    {
264
        $metadata = new ClassMetadata('Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\AssociatedEntity');
265
266
        $metadata->fieldMappings = array(
267
            'plainField' => array(
268
                'fieldName'  => 'plainField',
269
                'columnName' => 'plainField',
270
                'type'       => 'string',
271
            ),
272
        );
273
274
        return $metadata;
275
    }
276
277
    public function getMetadataForContainerEntity()
278
    {
279
        $containerEntityClass = 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\ContainerEntity';
280
        $associatedEntityClass = 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\AssociatedEntity';
281
        $embeddedEntityClass = 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Embeddable\EmbeddedEntity';
282
283
        $metadata = new ClassMetadata($containerEntityClass);
284
285
        $metadata->fieldMappings = array(
286
            'plainField' => array(
287
                'fieldName'  => 'plainField',
288
                'columnName' => 'plainField',
289
                'type'       => 'integer',
290
            ),
291
        );
292
293
        $metadata->associationMappings['associatedEntity'] = array(
294
            'fieldName'    => 'associatedEntity',
295
            'targetEntity' => $associatedEntityClass,
296
            'sourceEntity' => $containerEntityClass,
297
        );
298
299
        $metadata->embeddedClasses['embeddedEntity'] = array(
300
            'class'        => $embeddedEntityClass,
301
            'columnPrefix' => 'embeddedEntity',
302
        );
303
304
        $metadata->inlineEmbeddable('embeddedEntity', $this->getMetadataForEmbeddedEntity());
305
306
        return $metadata;
307
    }
308
309
    public function testNonIntegerIdentifierType()
310
    {
311
        $entity = new UuidEntity();
312
313
        $meta = $this->getMockBuilder('Doctrine\ORM\Mapping\ClassMetadataInfo')
314
            ->disableOriginalConstructor()
315
            ->getMock();
316
        $meta->expects($this->any())
317
            ->method('getIdentifierValues')
318
            ->willReturn(array($entity->getId()));
319
        $meta->expects($this->any())
320
            ->method('getTypeOfField')
321
            ->willReturn(UuidType::NAME);
322
323
        $mf = $this->getMockBuilder('Doctrine\ORM\Mapping\ClassMetadataFactory')
324
            ->disableOriginalConstructor()
325
            ->getMock();
326
        $mf->expects($this->any())
327
            ->method('getMetadataFor')
328
            ->willReturn($meta);
329
330
        $platform = $this->getMockBuilder('Doctrine\DBAL\Platforms\AbstractPlatform')
331
            ->disableOriginalConstructor()
332
            ->getMock();
333
334
        $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
335
            ->disableOriginalConstructor()
336
            ->getMock();
337
        $conn->expects($this->any())
338
            ->method('getDatabasePlatform')
339
            ->willReturn($platform);
340
341
        $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
342
            ->disableOriginalConstructor()
343
            ->getMock();
344
        $em->expects($this->any())
345
            ->method('getMetadataFactory')
346
            ->willReturn($mf);
347
        $em->expects($this->any())
348
            ->method('getConnection')
349
            ->willReturn($conn);
350
351
        $registry = $this->getMockBuilder('Symfony\Bridge\Doctrine\RegistryInterface')
352
            ->disableOriginalConstructor()
353
            ->getMock();
354
        $registry->expects($this->any())
355
            ->method('getManagerForClass')
356
            ->willReturn($em);
357
358
        $manager  = new ModelManager($registry);
359
        $result = $manager->getIdentifierValues($entity);
360
361
        $this->assertEquals($entity->getId()->toString(), $result[0]);
362
    }
363
}
364