Completed
Push — master ( d8d13a...e3b085 )
by
unknown
14:53
created

tests/Builder/FormContractorTest.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\DoctrineMongoDBAdminBundle\Tests\Builder;
15
16
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
17
use PHPUnit\Framework\TestCase;
18
use Sonata\AdminBundle\Admin\AdminInterface;
19
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
20
use Sonata\AdminBundle\Form\Type\AdminType;
21
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
22
use Sonata\AdminBundle\Form\Type\ModelHiddenType;
23
use Sonata\AdminBundle\Form\Type\ModelListType;
24
use Sonata\AdminBundle\Form\Type\ModelType;
25
use Sonata\AdminBundle\Model\ModelManagerInterface;
26
use Sonata\CoreBundle\Form\Type\CollectionType as DeprecatedCollectionType;
27
use Sonata\DoctrineMongoDBAdminBundle\Builder\FormContractor;
28
use Sonata\DoctrineMongoDBAdminBundle\Model\ModelManager;
29
use Sonata\Form\Type\CollectionType;
30
use Symfony\Component\Form\FormBuilderInterface;
31
use Symfony\Component\Form\FormFactoryInterface;
32
33
class FormContractorTest extends TestCase
34
{
35
    /**
36
     * @var FormFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
37
     */
38
    private $formFactory;
39
40
    /**
41
     * @var FormContractor
42
     */
43
    private $formContractor;
44
45
    protected function setUp(): void
46
    {
47
        $this->formFactory = $this->createMock(FormFactoryInterface::class);
48
49
        $this->formContractor = new FormContractor($this->formFactory);
50
    }
51
52
    public function testGetFormBuilder(): void
53
    {
54
        $this->formFactory->expects($this->once())->method('createNamedBuilder')
0 ignored issues
show
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Symfony\Component\Form\FormFactoryInterface.

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...
55
            ->willReturn($this->createMock(FormBuilderInterface::class));
56
57
        $this->assertInstanceOf(
58
            FormBuilderInterface::class,
59
            $this->formContractor->getFormBuilder('test', ['foo' => 'bar'])
60
        );
61
    }
62
63
    public function testDefaultOptionsForSonataFormTypes(): void
64
    {
65
        $admin = $this->createMock(AdminInterface::class);
66
        $modelManager = $this->createMock(ModelManagerInterface::class);
67
        $modelClass = 'FooEntity';
68
69
        $admin->method('getModelManager')->willReturn($modelManager);
70
        $admin->method('getClass')->willReturn($modelClass);
71
72
        $fieldDescription = $this->createMock(FieldDescriptionInterface::class);
73
        $fieldDescription->method('getAdmin')->willReturn($admin);
74
        $fieldDescription->method('getTargetEntity')->willReturn($modelClass);
75
        $fieldDescription->method('getAssociationAdmin')->willReturn($admin);
76
77
        // NEXT_MAJOR: Use only FQCNs when dropping support for Symfony 2.8
78
        $modelTypes = [
79
            'sonata_type_model',
80
            'sonata_type_model_list',
81
            'sonata_type_model_hidden',
82
            'sonata_type_model_autocomplete',
83
            ModelType::class,
84
            ModelListType::class,
85
            ModelHiddenType::class,
86
            ModelAutocompleteType::class,
87
        ];
88
        $adminTypes = [
89
            'sonata_type_admin',
90
            AdminType::class,
91
        ];
92
        $collectionTypes = [
93
            'sonata_type_collection',
94
            DeprecatedCollectionType::class,
95
        ];
96
97
        if (class_exists(CollectionType::class)) {
98
            $collectionTypes[] = CollectionType::class;
99
        }
100
101
        // model types
102
        foreach ($modelTypes as $formType) {
103
            $options = $this->formContractor->getDefaultOptions($formType, $fieldDescription);
104
            $this->assertSame($fieldDescription, $options['sonata_field_description']);
105
            $this->assertSame($modelClass, $options['class']);
106
            $this->assertSame($modelManager, $options['model_manager']);
107
        }
108
109
        // admin type
110
        $fieldDescription->method('getMappingType')->willReturn(ClassMetadataInfo::ONE);
111
        foreach ($adminTypes as $formType) {
112
            $options = $this->formContractor->getDefaultOptions($formType, $fieldDescription);
113
            $this->assertSame($fieldDescription, $options['sonata_field_description']);
114
            $this->assertSame($modelClass, $options['data_class']);
115
            $this->assertFalse($options['btn_add']);
116
            $this->assertFalse($options['delete']);
117
        }
118
119
        // collection type
120
        $fieldDescription->method('getMappingType')->willReturn(ClassMetadataInfo::MANY);
121
        foreach ($collectionTypes as $index => $formType) {
122
            $options = $this->formContractor->getDefaultOptions($formType, $fieldDescription);
123
            $this->assertSame($fieldDescription, $options['sonata_field_description']);
124
            $this->assertSame(AdminType::class, $options['type']);
125
            $this->assertTrue($options['modifiable']);
126
            $this->assertSame($fieldDescription, $options['type_options']['sonata_field_description']);
127
            $this->assertSame($modelClass, $options['type_options']['data_class']);
128
        }
129
    }
130
131
    public function testAdminClassAttachForNotMappedField(): void
132
    {
133
        // Given
134
        $modelManager = $this->createMock(ModelManager::class);
135
        $modelManager->method('hasMetadata')->willReturn(false);
136
137
        $admin = $this->createMock(AdminInterface::class);
138
        $admin->method('getModelManager')->willReturn($modelManager);
139
140
        $fieldDescription = $this->createMock(FieldDescriptionInterface::class);
141
        $fieldDescription->method('getMappingType')->willReturn('one');
142
        $fieldDescription->method('getType')->willReturn('sonata_type_model_list');
143
        $fieldDescription->method('getOption')->with($this->logicalOr(
144
            $this->equalTo('edit'),
145
            $this->equalTo('admin_code')
146
        ))->willReturn('sonata.admin.code');
147
148
        // Then
149
        $admin
150
            ->expects($this->once())
151
            ->method('attachAdminClass')
152
            ->with($fieldDescription)
153
        ;
154
155
        // When
156
        $this->formContractor->fixFieldDescription($admin, $fieldDescription);
157
    }
158
}
159