Completed
Push — 3.x ( 640d2f...56238c )
by Oskar
03:08
created

DatagridMapperTest::testKeys()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
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\Admin\FieldDescriptionInterface;
21
use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
22
use Sonata\AdminBundle\Datagrid\Datagrid;
23
use Sonata\AdminBundle\Datagrid\DatagridMapper;
24
use Sonata\AdminBundle\Datagrid\PagerInterface;
25
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
26
use Sonata\AdminBundle\Filter\Filter;
27
use Sonata\AdminBundle\Filter\FilterInterface;
28
use Sonata\AdminBundle\Model\ModelManagerInterface;
29
use Symfony\Component\Form\Extension\Core\Type\TextType;
30
use Symfony\Component\Form\FormBuilder;
31
32
/**
33
 * @author Andrej Hudec <[email protected]>
34
 */
35
class DatagridMapperTest extends TestCase
36
{
37
    private const DEFAULT_GRANTED_ROLE = 'ROLE_ADMIN_BAZ';
38
39
    /**
40
     * @var DatagridMapper
41
     */
42
    private $datagridMapper;
43
44
    /**
45
     * @var Datagrid
46
     */
47
    private $datagrid;
48
49
    protected function setUp(): void
50
    {
51
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
52
53
        $proxyQuery = $this->createMock(ProxyQueryInterface::class);
54
        $pager = $this->createMock(PagerInterface::class);
55
        $fieldDescriptionCollection = $this->createMock(FieldDescriptionCollection::class);
56
        $formBuilder = $this->getMockBuilder(FormBuilder::class)
57
                     ->disableOriginalConstructor()
58
                     ->getMock();
59
60
        $this->datagrid = new Datagrid($proxyQuery, $fieldDescriptionCollection, $pager, $formBuilder, []);
61
62
        $admin = $this->createMock(AdminInterface::class);
63
64
        $datagridBuilder
65
            ->method('addFilter')
66
            ->willReturnCallback(function (
67
                Datagrid $datagrid,
68
                ?string $type,
69
                FieldDescriptionInterface $fieldDescription,
70
                AdminInterface $admin
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...
71
            ): void {
72
                $fieldDescription->setType($type);
73
74
                $filter = $this->getMockForAbstractClass(Filter::class);
75
76
                $filter
77
                    ->method('getDefaultOptions')
78
                    ->willReturn(['foo_default_option' => 'bar_default']);
79
80
                $filter->initialize($fieldDescription->getName(), $fieldDescription->getOptions());
81
                $datagrid->addFilter($filter);
82
            });
83
84
        $modelManager = $this->createMock(ModelManagerInterface::class);
85
86
        $modelManager
87
            ->method('getNewFieldDescriptionInstance')
88
            ->willReturnCallback(function (?string $class, string $name, array $options = []): BaseFieldDescription {
89
                $fieldDescription = $this->getFieldDescriptionMock();
90
                $fieldDescription->setName($name);
91
                $fieldDescription->setOptions($options);
92
93
                return $fieldDescription;
94
            });
95
96
        $admin
97
            ->method('getModelManager')
98
            ->willReturn($modelManager);
99
100
        $admin
101
            ->method('isGranted')
102
            ->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...
103
                return self::DEFAULT_GRANTED_ROLE === $name;
104
            });
105
106
        $this->datagridMapper = new DatagridMapper($datagridBuilder, $this->datagrid, $admin);
107
    }
108
109
    public function testFluidInterface(): void
110
    {
111
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
112
113
        $this->assertSame($this->datagridMapper, $this->datagridMapper->add($fieldDescription, null, ['field_name' => 'fooFilterName']));
114
        $this->assertSame($this->datagridMapper, $this->datagridMapper->remove('fooName'));
115
        $this->assertSame($this->datagridMapper, $this->datagridMapper->reorder([]));
116
    }
117
118
    public function testGet(): void
119
    {
120
        $this->assertFalse($this->datagridMapper->has('fooName'));
121
122
        $fieldDescription = $this->getFieldDescriptionMock('foo.name', 'fooLabel');
123
124
        $this->datagridMapper->add($fieldDescription, null, ['field_name' => 'fooFilterName']);
125
126
        $filter = $this->datagridMapper->get('foo.name');
127
        $this->assertInstanceOf(FilterInterface::class, $filter);
128
        $this->assertSame('foo.name', $filter->getName());
129
        $this->assertSame('foo__name', $filter->getFormName());
130
        $this->assertSame(TextType::class, $filter->getFieldType());
131
        $this->assertSame('fooLabel', $filter->getLabel());
132
        $this->assertSame(['required' => false], $filter->getFieldOptions());
133
        $this->assertSame([
134
            'show_filter' => null,
135
            'advanced_filter' => true,
136
            'foo_default_option' => 'bar_default',
137
            'label' => 'fooLabel',
138
            'field_name' => 'fooFilterName',
139
            'placeholder' => 'short_object_description_placeholder',
140
            'link_parameters' => [],
141
        ], $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...
142
    }
143
144
    public function testGet2(): void
145
    {
146
        $this->assertFalse($this->datagridMapper->has('fooName'));
147
148
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
149
150
        $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']);
151
152
        $filter = $this->datagridMapper->get('fooName');
153
        $this->assertInstanceOf(FilterInterface::class, $filter);
154
        $this->assertSame('fooName', $filter->getName());
155
        $this->assertSame('fooName', $filter->getFormName());
156
        $this->assertSame('foo_field_type', $filter->getFieldType());
157
        $this->assertSame('fooLabel', $filter->getLabel());
158
        $this->assertSame(['foo_field_option' => 'baz'], $filter->getFieldOptions());
159
        $this->assertSame([
160
            'show_filter' => null,
161
            'advanced_filter' => true,
162
            'foo_default_option' => 'bar_custom',
163
            'label' => 'fooLabel',
164
            'field_name' => 'fooFilterName',
165
            'foo_filter_option' => 'foo_filter_option_value',
166
            'field_options' => ['foo_field_option' => 'baz'],
167
            'field_type' => 'foo_field_type',
168
            'placeholder' => 'short_object_description_placeholder',
169
            'link_parameters' => [],
170
        ], $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...
171
    }
172
173
    public function testAdd(): void
174
    {
175
        $this->datagridMapper->add('fooName');
176
177
        $this->assertTrue($this->datagridMapper->has('fooName'));
178
179
        $fieldDescription = $this->datagridMapper->get('fooName');
180
181
        $this->assertInstanceOf(FilterInterface::class, $fieldDescription);
182
        $this->assertSame('fooName', $fieldDescription->getName());
183
    }
184
185
    public function testAddWithoutFieldName(): void
186
    {
187
        $this->datagridMapper->add('foo.bar');
188
189
        $this->assertTrue($this->datagridMapper->has('foo.bar'));
190
191
        $fieldDescription = $this->datagridMapper->get('foo.bar');
192
193
        $this->assertInstanceOf(FilterInterface::class, $fieldDescription);
194
        $this->assertSame('foo.bar', $fieldDescription->getName());
195
        $this->assertSame('bar', $fieldDescription->getOption('field_name'));
196
    }
197
198
    public function testAddRemove(): void
199
    {
200
        $this->assertFalse($this->datagridMapper->has('fooName'));
201
202
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
203
204
        $this->datagridMapper->add($fieldDescription, null, ['field_name' => 'fooFilterName']);
205
        $this->assertTrue($this->datagridMapper->has('fooName'));
206
207
        $this->datagridMapper->remove('fooName');
208
        $this->assertFalse($this->datagridMapper->has('fooName'));
209
        $this->assertSame('fooFilterName', $fieldDescription->getOption('field_name'));
210
    }
211
212
    public function testAddException(): void
213
    {
214
        $this->expectException(\TypeError::class);
215
        $this->expectExceptionMessage(
216
            'Unknown field name in datagrid mapper. Field name should be either of FieldDescriptionInterface interface or string'
217
        );
218
219
        $this->datagridMapper->add(12345);
220
    }
221
222
    public function testAddDuplicateNameException(): void
223
    {
224
        $tmpNames = [];
225
        $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...
226
            ->expects($this->exactly(2))
227
            ->method('hasFilterFieldDescription')
228
            ->willReturnCallback(static function (string $name) use (&$tmpNames): bool {
229
                if (isset($tmpNames[$name])) {
230
                    return true;
231
                }
232
                $tmpNames[$name] = $name;
233
234
                return false;
235
            });
236
237
        $this->expectException(\LogicException::class);
238
        $this->expectExceptionMessage('Duplicate field name "fooName" in datagrid mapper. Names should be unique.');
239
240
        $this->datagridMapper->add('fooName');
241
        $this->datagridMapper->add('fooName');
242
    }
243
244
    public function testKeys(): void
245
    {
246
        $fieldDescription1 = $this->getFieldDescriptionMock('fooName1', 'fooLabel1');
247
        $fieldDescription2 = $this->getFieldDescriptionMock('fooName2', 'fooLabel2');
248
249
        $this->datagridMapper->add($fieldDescription1, null, ['field_name' => 'fooFilterName1']);
250
        $this->datagridMapper->add($fieldDescription2, null, ['field_name' => 'fooFilterName2']);
251
252
        $this->assertSame(['fooName1', 'fooName2'], $this->datagridMapper->keys());
253
    }
254
255
    public function testReorder(): void
256
    {
257
        $fieldDescription1 = $this->getFieldDescriptionMock('fooName1', 'fooLabel1');
258
        $fieldDescription2 = $this->getFieldDescriptionMock('fooName2', 'fooLabel2');
259
        $fieldDescription3 = $this->getFieldDescriptionMock('fooName3', 'fooLabel3');
260
        $fieldDescription4 = $this->getFieldDescriptionMock('fooName4', 'fooLabel4');
261
262
        $this->datagridMapper->add($fieldDescription1, null, ['field_name' => 'fooFilterName1']);
263
        $this->datagridMapper->add($fieldDescription2, null, ['field_name' => 'fooFilterName2']);
264
        $this->datagridMapper->add($fieldDescription3, null, ['field_name' => 'fooFilterName3']);
265
        $this->datagridMapper->add($fieldDescription4, null, ['field_name' => 'fooFilterName4']);
266
267
        $this->assertSame([
268
            'fooName1',
269
            'fooName2',
270
            'fooName3',
271
            'fooName4',
272
        ], array_keys($this->datagrid->getFilters()));
273
274
        $this->datagridMapper->reorder(['fooName3', 'fooName2', 'fooName1', 'fooName4']);
275
276
        $this->assertSame([
277
            'fooName3',
278
            'fooName2',
279
            'fooName1',
280
            'fooName4',
281
        ], array_keys($this->datagrid->getFilters()));
282
    }
283
284
    public function testAddOptionRole(): void
285
    {
286
        $this->datagridMapper->add('bar', 'bar');
287
288
        $this->assertTrue($this->datagridMapper->has('bar'));
289
290
        $this->datagridMapper->add('quux', 'bar', [], null, null, ['role' => 'ROLE_QUX']);
291
292
        $this->assertTrue($this->datagridMapper->has('bar'));
293
        $this->assertFalse($this->datagridMapper->has('quux'));
294
295
        $this->datagridMapper
296
            ->add('foobar', 'bar', [], null, null, ['role' => self::DEFAULT_GRANTED_ROLE])
297
            ->add('foo', 'bar', [], null, null, ['role' => 'ROLE_QUX'])
298
            ->add('baz', 'bar');
299
300
        $this->assertTrue($this->datagridMapper->has('foobar'));
301
        $this->assertFalse($this->datagridMapper->has('foo'));
302
        $this->assertTrue($this->datagridMapper->has('baz'));
303
    }
304
305
    private function getFieldDescriptionMock(?string $name = null, ?string $label = null): BaseFieldDescription
306
    {
307
        $fieldDescription = $this->getMockForAbstractClass(BaseFieldDescription::class);
308
309
        if (null !== $name) {
310
            $fieldDescription->setName($name);
311
        }
312
313
        if (null !== $label) {
314
            $fieldDescription->setOption('label', $label);
315
        }
316
317
        return $fieldDescription;
318
    }
319
}
320