Completed
Push — master ( e6c9d7...cc6bd7 )
by Grégoire
12:23
created

DatagridMapperTest::testAddOptionRole()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.6
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\AdminBundle\Tests\Datagrid;
15
16
use PHPUnit\Framework\TestCase;
17
use Sonata\AdminBundle\Admin\AdminInterface;
18
use Sonata\AdminBundle\Admin\BaseFieldDescription;
19
use Sonata\AdminBundle\Admin\FieldDescriptionCollection;
20
use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
21
use Sonata\AdminBundle\Datagrid\Datagrid;
22
use Sonata\AdminBundle\Datagrid\DatagridMapper;
23
use Sonata\AdminBundle\Datagrid\PagerInterface;
24
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
25
use Sonata\AdminBundle\Filter\Filter;
26
use Sonata\AdminBundle\Filter\FilterInterface;
27
use Sonata\AdminBundle\Model\ModelManagerInterface;
28
use Symfony\Component\Form\Extension\Core\Type\TextType;
29
use Symfony\Component\Form\FormBuilder;
30
31
/**
32
 * @author Andrej Hudec <[email protected]>
33
 */
34
class DatagridMapperTest extends TestCase
35
{
36
    private const DEFAULT_GRANTED_ROLE = 'ROLE_ADMIN_BAZ';
37
38
    /**
39
     * @var DatagridMapper
40
     */
41
    private $datagridMapper;
42
43
    /**
44
     * @var Datagrid
45
     */
46
    private $datagrid;
47
48
    protected function setUp(): void
49
    {
50
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
51
52
        $proxyQuery = $this->createMock(ProxyQueryInterface::class);
53
        $pager = $this->createMock(PagerInterface::class);
54
        $fieldDescriptionCollection = $this->createMock(FieldDescriptionCollection::class);
55
        $formBuilder = $this->getMockBuilder(FormBuilder::class)
56
                     ->disableOriginalConstructor()
57
                     ->getMock();
58
59
        $this->datagrid = new Datagrid($proxyQuery, $fieldDescriptionCollection, $pager, $formBuilder, []);
60
61
        $admin = $this->createMock(AdminInterface::class);
62
63
        $datagridBuilder->expects($this->any())
64
            ->method('addFilter')
65
            ->willReturnCallback(function ($datagrid, $type, $fieldDescription, $admin): void {
0 ignored issues
show
Unused Code introduced by
The parameter $admin is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
66
                $fieldDescription->setType($type);
67
68
                $filter = $this->getMockForAbstractClass(Filter::class);
69
70
                $filter->expects($this->any())
71
                    ->method('getDefaultOptions')
72
                    ->willReturn(['foo_default_option' => 'bar_default']);
73
74
                $filter->initialize($fieldDescription->getName(), $fieldDescription->getOptions());
75
                $datagrid->addFilter($filter);
76
            });
77
78
        $modelManager = $this->createMock(ModelManagerInterface::class);
79
80
        $modelManager->expects($this->any())
81
            ->method('getNewFieldDescriptionInstance')
82
            ->willReturnCallback(function ($class, $name, array $options = []) {
83
                $fieldDescription = $this->getFieldDescriptionMock();
84
                $fieldDescription->setName($name);
85
                $fieldDescription->setOptions($options);
86
87
                return $fieldDescription;
88
            });
89
90
        $admin->expects($this->any())
91
            ->method('getModelManager')
92
            ->willReturn($modelManager);
93
94
        $admin->expects($this->any())
95
            ->method('isGranted')
96
            ->willReturnCallback(static function (string $name, object $object = null): bool {
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
97
                return self::DEFAULT_GRANTED_ROLE === $name;
98
            });
99
100
        $this->datagridMapper = new DatagridMapper($datagridBuilder, $this->datagrid, $admin);
101
    }
102
103
    public function testFluidInterface(): void
104
    {
105
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
106
107
        $this->assertSame($this->datagridMapper, $this->datagridMapper->add($fieldDescription, null, ['field_name' => 'fooFilterName']));
0 ignored issues
show
Documentation introduced by
$fieldDescription is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
108
        $this->assertSame($this->datagridMapper, $this->datagridMapper->remove('fooName'));
109
        $this->assertSame($this->datagridMapper, $this->datagridMapper->reorder([]));
110
    }
111
112
    public function testGet(): void
113
    {
114
        $this->assertFalse($this->datagridMapper->has('fooName'));
115
116
        $fieldDescription = $this->getFieldDescriptionMock('foo.name', 'fooLabel');
117
118
        $this->datagridMapper->add($fieldDescription, null, ['field_name' => 'fooFilterName']);
0 ignored issues
show
Documentation introduced by
$fieldDescription is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
119
120
        $filter = $this->datagridMapper->get('foo.name');
121
        $this->assertInstanceOf(FilterInterface::class, $filter);
122
        $this->assertSame('foo.name', $filter->getName());
123
        $this->assertSame('foo__name', $filter->getFormName());
124
        $this->assertSame(TextType::class, $filter->getFieldType());
125
        $this->assertSame('fooLabel', $filter->getLabel());
126
        $this->assertSame(['required' => false], $filter->getFieldOptions());
127
        $this->assertSame([
128
            'show_filter' => null,
129
            'advanced_filter' => true,
130
            'foo_default_option' => 'bar_default',
131
            'label' => 'fooLabel',
132
            'field_name' => 'fooFilterName',
133
            'placeholder' => 'short_object_description_placeholder',
134
            'link_parameters' => [],
135
        ], $filter->getOptions());
0 ignored issues
show
Bug introduced by
The method getOptions() does not exist on Sonata\AdminBundle\Filter\FilterInterface. Did you maybe mean getOption()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
136
    }
137
138
    public function testGet2(): void
139
    {
140
        $this->assertFalse($this->datagridMapper->has('fooName'));
141
142
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
143
144
        $this->datagridMapper->add($fieldDescription, 'foo_type', ['field_name' => 'fooFilterName', 'foo_filter_option' => 'foo_filter_option_value', 'foo_default_option' => 'bar_custom'], 'foo_field_type', ['foo_field_option' => 'baz']);
0 ignored issues
show
Documentation introduced by
$fieldDescription is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
145
146
        $filter = $this->datagridMapper->get('fooName');
147
        $this->assertInstanceOf(FilterInterface::class, $filter);
148
        $this->assertSame('fooName', $filter->getName());
149
        $this->assertSame('fooName', $filter->getFormName());
150
        $this->assertSame('foo_field_type', $filter->getFieldType());
151
        $this->assertSame('fooLabel', $filter->getLabel());
152
        $this->assertSame(['foo_field_option' => 'baz'], $filter->getFieldOptions());
153
        $this->assertSame([
154
            'show_filter' => null,
155
            'advanced_filter' => true,
156
            'foo_default_option' => 'bar_custom',
157
            'label' => 'fooLabel',
158
            'field_name' => 'fooFilterName',
159
            'foo_filter_option' => 'foo_filter_option_value',
160
            'field_options' => ['foo_field_option' => 'baz'],
161
            'field_type' => 'foo_field_type',
162
            'placeholder' => 'short_object_description_placeholder',
163
            'link_parameters' => [],
164
        ], $filter->getOptions());
0 ignored issues
show
Bug introduced by
The method getOptions() does not exist on Sonata\AdminBundle\Filter\FilterInterface. Did you maybe mean getOption()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
165
    }
166
167
    public function testAdd(): void
168
    {
169
        $this->datagridMapper->add('fooName');
170
171
        $this->assertTrue($this->datagridMapper->has('fooName'));
172
173
        $fieldDescription = $this->datagridMapper->get('fooName');
174
175
        $this->assertInstanceOf(FilterInterface::class, $fieldDescription);
176
        $this->assertSame('fooName', $fieldDescription->getName());
177
    }
178
179
    public function testAddWithoutFieldName(): void
180
    {
181
        $this->datagridMapper->add('foo.bar');
182
183
        $this->assertTrue($this->datagridMapper->has('foo.bar'));
184
185
        $fieldDescription = $this->datagridMapper->get('foo.bar');
186
187
        $this->assertInstanceOf(FilterInterface::class, $fieldDescription);
188
        $this->assertSame('foo.bar', $fieldDescription->getName());
189
        $this->assertSame('bar', $fieldDescription->getOption('field_name'));
190
    }
191
192
    public function testAddRemove(): void
193
    {
194
        $this->assertFalse($this->datagridMapper->has('fooName'));
195
196
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
197
198
        $this->datagridMapper->add($fieldDescription, null, ['field_name' => 'fooFilterName']);
0 ignored issues
show
Documentation introduced by
$fieldDescription is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
199
        $this->assertTrue($this->datagridMapper->has('fooName'));
200
201
        $this->datagridMapper->remove('fooName');
202
        $this->assertFalse($this->datagridMapper->has('fooName'));
203
        $this->assertSame('fooFilterName', $fieldDescription->getOption('field_name'));
204
    }
205
206
    public function testAddException(): void
207
    {
208
        $this->expectException(\RuntimeException::class, 'Unknown field name in datagrid mapper. Field name should be either of FieldDescriptionInterface interface or string');
209
210
        $this->datagridMapper->add(12345);
211
    }
212
213
    public function testAddDuplicateNameException(): void
214
    {
215
        $tmpNames = [];
216
        $this->datagridMapper->getAdmin()
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
217
            ->expects($this->exactly(2))
218
            ->method('hasFilterFieldDescription')
219
            ->willReturnCallback(static function ($name) use (&$tmpNames) {
220
                if (isset($tmpNames[$name])) {
221
                    return true;
222
                }
223
                $tmpNames[$name] = $name;
224
225
                return false;
226
            });
227
228
        $this->expectException(\RuntimeException::class, 'Duplicate field name "fooName" in datagrid mapper. Names should be unique.');
229
230
        $this->datagridMapper->add('fooName');
231
        $this->datagridMapper->add('fooName');
232
    }
233
234
    public function testKeys(): void
235
    {
236
        $fieldDescription1 = $this->getFieldDescriptionMock('fooName1', 'fooLabel1');
237
        $fieldDescription2 = $this->getFieldDescriptionMock('fooName2', 'fooLabel2');
238
239
        $this->datagridMapper->add($fieldDescription1, null, ['field_name' => 'fooFilterName1']);
0 ignored issues
show
Documentation introduced by
$fieldDescription1 is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
240
        $this->datagridMapper->add($fieldDescription2, null, ['field_name' => 'fooFilterName2']);
0 ignored issues
show
Documentation introduced by
$fieldDescription2 is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
241
242
        $this->assertSame(['fooName1', 'fooName2'], $this->datagridMapper->keys());
243
    }
244
245
    public function testReorder(): void
246
    {
247
        $fieldDescription1 = $this->getFieldDescriptionMock('fooName1', 'fooLabel1');
248
        $fieldDescription2 = $this->getFieldDescriptionMock('fooName2', 'fooLabel2');
249
        $fieldDescription3 = $this->getFieldDescriptionMock('fooName3', 'fooLabel3');
250
        $fieldDescription4 = $this->getFieldDescriptionMock('fooName4', 'fooLabel4');
251
252
        $this->datagridMapper->add($fieldDescription1, null, ['field_name' => 'fooFilterName1']);
0 ignored issues
show
Documentation introduced by
$fieldDescription1 is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
253
        $this->datagridMapper->add($fieldDescription2, null, ['field_name' => 'fooFilterName2']);
0 ignored issues
show
Documentation introduced by
$fieldDescription2 is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
254
        $this->datagridMapper->add($fieldDescription3, null, ['field_name' => 'fooFilterName3']);
0 ignored issues
show
Documentation introduced by
$fieldDescription3 is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
255
        $this->datagridMapper->add($fieldDescription4, null, ['field_name' => 'fooFilterName4']);
0 ignored issues
show
Documentation introduced by
$fieldDescription4 is of type object<Sonata\AdminBundl...n\BaseFieldDescription>, 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...
256
257
        $this->assertSame([
258
            'fooName1',
259
            'fooName2',
260
            'fooName3',
261
            'fooName4',
262
        ], array_keys($this->datagrid->getFilters()));
263
264
        $this->datagridMapper->reorder(['fooName3', 'fooName2', 'fooName1', 'fooName4']);
265
266
        $this->assertSame([
267
            'fooName3',
268
            'fooName2',
269
            'fooName1',
270
            'fooName4',
271
        ], array_keys($this->datagrid->getFilters()));
272
    }
273
274
    public function testAddOptionRole(): void
275
    {
276
        $this->datagridMapper->add('bar', 'bar');
277
278
        $this->assertTrue($this->datagridMapper->has('bar'));
279
280
        $this->datagridMapper->add('quux', 'bar', [], null, null, ['role' => 'ROLE_QUX']);
281
282
        $this->assertTrue($this->datagridMapper->has('bar'));
283
        $this->assertFalse($this->datagridMapper->has('quux'));
284
285
        $this->datagridMapper
286
            ->add('foobar', 'bar', [], null, null, ['role' => self::DEFAULT_GRANTED_ROLE])
287
            ->add('foo', 'bar', [], null, null, ['role' => 'ROLE_QUX'])
288
            ->add('baz', 'bar');
289
290
        $this->assertTrue($this->datagridMapper->has('foobar'));
291
        $this->assertFalse($this->datagridMapper->has('foo'));
292
        $this->assertTrue($this->datagridMapper->has('baz'));
293
    }
294
295
    private function getFieldDescriptionMock(?string $name = null, ?string $label = null): BaseFieldDescription
296
    {
297
        $fieldDescription = $this->getMockForAbstractClass(BaseFieldDescription::class);
298
299
        if (null !== $name) {
300
            $fieldDescription->setName($name);
301
        }
302
303
        if (null !== $label) {
304
            $fieldDescription->setOption('label', $label);
305
        }
306
307
        return $fieldDescription;
308
    }
309
}
310