ShowMapperTest   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 576
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 8
dl 0
loc 576
rs 9.52
c 0
b 0
f 0

33 Methods

Rating   Name   Duplication   Size   Complexity  
B setUp() 0 81 2
A testFluidInterface() 0 8 1
A testGet() 0 9 1
A testAdd() 0 12 1
A testIfTrueApply() 0 13 1
A testIfTrueApplyWithTab() 0 13 1
A testIfTrueNotApply() 0 8 1
A testIfTrueNotApplyWithTab() 0 8 1
A testIfTrueCombination() 0 15 1
A testIfFalseApply() 0 13 1
A testIfFalseApplyWithTab() 0 13 1
A testIfFalseNotApply() 0 8 1
A testIfFalseNotApplyWithTab() 0 8 1
A testIfFalseCombination() 0 15 1
A testIfTrueNested() 0 12 1
A testIfFalseNested() 0 12 1
A testIfCombinationNested() 0 12 1
A testIfFalseCombinationNested2() 0 12 1
A testIfFalseCombinationNested3() 0 12 1
A testIfFalseCombinationNested4() 0 12 1
A testAddRemove() 0 12 1
A testAddException() 0 7 1
A testAddDuplicateFieldNameException() 0 11 1
A testKeys() 0 10 1
A testReorder() 0 46 1
A testGroupRemovingWithoutTab() 0 9 1
A testGroupRemovingWithTab() 0 9 1
A testGroupRemovingWithoutTabAndWithTabRemoving() 0 10 1
A testGroupRemovingWithTabAndWithTabRemoving() 0 10 1
A testEmptyFieldLabel() 0 10 1
A testAddOptionRole() 0 27 1
A cleanShowMapper() 0 38 1
A getFieldDescriptionMock() 0 14 3
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\Show;
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\ShowBuilderInterface;
22
use Sonata\AdminBundle\Model\ModelManagerInterface;
23
use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface;
24
use Sonata\AdminBundle\Show\ShowMapper;
25
use Sonata\AdminBundle\Tests\App\Builder\ShowBuilder;
26
use Sonata\AdminBundle\Tests\Fixtures\Admin\CleanAdmin;
27
use Sonata\AdminBundle\Translator\NoopLabelTranslatorStrategy;
28
29
/**
30
 * Test for ShowMapper.
31
 *
32
 * @author Andrej Hudec <[email protected]>
33
 */
34
class ShowMapperTest extends TestCase
35
{
36
    private const DEFAULT_GRANTED_ROLE = 'ROLE_ADMIN_BAZ';
37
38
    /**
39
     * @var ShowMapper
40
     */
41
    private $showMapper;
42
43
    /**
44
     * @var AdminInterface
45
     */
46
    private $admin;
47
48
    /**
49
     * @var ShowBuilderInterface
50
     */
51
    private $showBuilder;
52
53
    /**
54
     * @var FieldDescriptionCollection
55
     */
56
    private $fieldDescriptionCollection;
57
58
    /**
59
     * @var array
60
     */
61
    private $groups;
62
63
    /**
64
     * @var array
65
     */
66
    private $listShowFields;
67
68
    protected function setUp(): void
69
    {
70
        $this->showBuilder = $this->getMockForAbstractClass(ShowBuilderInterface::class);
71
        $this->fieldDescriptionCollection = new FieldDescriptionCollection();
72
        $this->admin = $this->getMockForAbstractClass(AdminInterface::class);
73
74
        $this->admin
75
            ->method('getLabel')
76
            ->willReturn('AdminLabel');
77
78
        $this->admin
79
            ->method('getShowTabs')
80
            ->willReturn([]);
81
82
        $this->groups = [];
83
        $this->listShowFields = [];
84
85
        $this->admin
86
            ->method('getShowGroups')
87
            ->willReturnCallback(function () {
88
                return $this->groups;
89
            });
90
91
        $this->admin
92
            ->method('setShowGroups')
93
            ->willReturnCallback(function (array $showGroups): void {
94
                $this->groups = $showGroups;
95
            });
96
97
        $this->admin
98
            ->method('reorderShowGroup')
99
            ->willReturnCallback(function (string $group, array $keys): void {
100
                $this->groups[$group]['fields'] = array_merge(array_flip($keys), $this->groups[$group]['fields']);
101
            });
102
103
        $modelManager = $this->getMockForAbstractClass(ModelManagerInterface::class);
104
105
        $modelManager
106
            ->method('getNewFieldDescriptionInstance')
107
            ->willReturnCallback(function (?string $class, string $name, array $options = []) {
108
                $fieldDescription = $this->getFieldDescriptionMock();
109
                $fieldDescription->setName($name);
110
                $fieldDescription->setOptions($options);
111
112
                return $fieldDescription;
113
            });
114
115
        $this->admin
116
            ->method('getModelManager')
117
            ->willReturn($modelManager);
118
119
        $labelTranslatorStrategy = new NoopLabelTranslatorStrategy();
120
121
        $this->admin
122
            ->method('getLabelTranslatorStrategy')
123
            ->willReturn($labelTranslatorStrategy);
124
125
        $this->admin
126
            ->method('hasShowFieldDescription')
127
            ->willReturnCallback(function (string $name): bool {
128
                if (isset($this->listShowFields[$name])) {
129
                    return true;
130
                }
131
                $this->listShowFields[$name] = true;
132
133
                return false;
134
            });
135
136
        $this->showBuilder
137
            ->method('addField')
138
            ->willReturnCallback(static function (
139
                FieldDescriptionCollection $list,
140
                ?string $type,
141
                FieldDescriptionInterface $fieldDescription,
142
                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...
143
            ): void {
144
                $list->add($fieldDescription);
145
            });
146
147
        $this->showMapper = new ShowMapper($this->showBuilder, $this->fieldDescriptionCollection, $this->admin);
148
    }
149
150
    public function testFluidInterface(): void
151
    {
152
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
153
154
        $this->assertSame($this->showMapper, $this->showMapper->add($fieldDescription));
155
        $this->assertSame($this->showMapper, $this->showMapper->remove('fooName'));
156
        $this->assertSame($this->showMapper, $this->showMapper->reorder([]));
157
    }
158
159
    public function testGet(): void
160
    {
161
        $this->assertFalse($this->showMapper->has('fooName'));
162
163
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
164
165
        $this->showMapper->add($fieldDescription);
166
        $this->assertSame($fieldDescription, $this->showMapper->get('fooName'));
167
    }
168
169
    public function testAdd(): void
170
    {
171
        $this->showMapper->add('fooName');
172
173
        $this->assertTrue($this->showMapper->has('fooName'));
174
175
        $fieldDescription = $this->showMapper->get('fooName');
176
177
        $this->assertInstanceOf(FieldDescriptionInterface::class, $fieldDescription);
178
        $this->assertSame('fooName', $fieldDescription->getName());
179
        $this->assertSame('fooName', $fieldDescription->getOption('label'));
180
    }
181
182
    public function testIfTrueApply(): void
183
    {
184
        $this->showMapper->ifTrue(true);
185
        $this->showMapper->add('fooName');
186
        $this->showMapper->ifEnd();
187
188
        $this->assertTrue($this->showMapper->has('fooName'));
189
        $fieldDescription = $this->showMapper->get('fooName');
190
191
        $this->assertInstanceOf(FieldDescriptionInterface::class, $fieldDescription);
192
        $this->assertSame('fooName', $fieldDescription->getName());
193
        $this->assertSame('fooName', $fieldDescription->getOption('label'));
194
    }
195
196
    public function testIfTrueApplyWithTab(): void
197
    {
198
        $this->showMapper->ifTrue(true);
199
        $this->showMapper->tab('fooTab')->add('fooName')->end();
200
        $this->showMapper->ifEnd();
201
202
        $this->assertTrue($this->showMapper->has('fooName'));
203
        $fieldDescription = $this->showMapper->get('fooName');
204
205
        $this->assertInstanceOf(FieldDescriptionInterface::class, $fieldDescription);
206
        $this->assertSame('fooName', $fieldDescription->getName());
207
        $this->assertSame('fooName', $fieldDescription->getOption('label'));
208
    }
209
210
    public function testIfTrueNotApply(): void
211
    {
212
        $this->showMapper->ifTrue(false);
213
        $this->showMapper->add('fooName');
214
        $this->showMapper->ifEnd();
215
216
        $this->assertFalse($this->showMapper->has('fooName'));
217
    }
218
219
    public function testIfTrueNotApplyWithTab(): void
220
    {
221
        $this->showMapper->ifTrue(false);
222
        $this->showMapper->tab('fooTab')->add('fooName')->end();
223
        $this->showMapper->ifEnd();
224
225
        $this->assertFalse($this->showMapper->has('fooName'));
226
    }
227
228
    public function testIfTrueCombination(): void
229
    {
230
        $this->showMapper->ifTrue(false);
231
        $this->showMapper->add('fooName');
232
        $this->showMapper->ifEnd();
233
        $this->showMapper->add('barName');
234
235
        $this->assertFalse($this->showMapper->has('fooName'));
236
        $this->assertTrue($this->showMapper->has('barName'));
237
        $fieldDescription = $this->showMapper->get('barName');
238
239
        $this->assertInstanceOf(FieldDescriptionInterface::class, $fieldDescription);
240
        $this->assertSame('barName', $fieldDescription->getName());
241
        $this->assertSame('barName', $fieldDescription->getOption('label'));
242
    }
243
244
    public function testIfFalseApply(): void
245
    {
246
        $this->showMapper->ifFalse(false);
247
        $this->showMapper->add('fooName');
248
        $this->showMapper->ifEnd();
249
250
        $this->assertTrue($this->showMapper->has('fooName'));
251
        $fieldDescription = $this->showMapper->get('fooName');
252
253
        $this->assertInstanceOf(FieldDescriptionInterface::class, $fieldDescription);
254
        $this->assertSame('fooName', $fieldDescription->getName());
255
        $this->assertSame('fooName', $fieldDescription->getOption('label'));
256
    }
257
258
    public function testIfFalseApplyWithTab(): void
259
    {
260
        $this->showMapper->ifFalse(false);
261
        $this->showMapper->tab('fooTab')->add('fooName')->end();
262
        $this->showMapper->ifEnd();
263
264
        $this->assertTrue($this->showMapper->has('fooName'));
265
        $fieldDescription = $this->showMapper->get('fooName');
266
267
        $this->assertInstanceOf(FieldDescriptionInterface::class, $fieldDescription);
268
        $this->assertSame('fooName', $fieldDescription->getName());
269
        $this->assertSame('fooName', $fieldDescription->getOption('label'));
270
    }
271
272
    public function testIfFalseNotApply(): void
273
    {
274
        $this->showMapper->ifFalse(true);
275
        $this->showMapper->add('fooName');
276
        $this->showMapper->ifEnd();
277
278
        $this->assertFalse($this->showMapper->has('fooName'));
279
    }
280
281
    public function testIfFalseNotApplyWithTab(): void
282
    {
283
        $this->showMapper->ifFalse(true);
284
        $this->showMapper->tab('fooTab')->add('fooName')->end();
285
        $this->showMapper->ifEnd();
286
287
        $this->assertFalse($this->showMapper->has('fooName'));
288
    }
289
290
    public function testIfFalseCombination(): void
291
    {
292
        $this->showMapper->ifFalse(true);
293
        $this->showMapper->add('fooName');
294
        $this->showMapper->ifEnd();
295
        $this->showMapper->add('barName');
296
297
        $this->assertFalse($this->showMapper->has('fooName'));
298
        $this->assertTrue($this->showMapper->has('barName'));
299
        $fieldDescription = $this->showMapper->get('barName');
300
301
        $this->assertInstanceOf(FieldDescriptionInterface::class, $fieldDescription);
302
        $this->assertSame('barName', $fieldDescription->getName());
303
        $this->assertSame('barName', $fieldDescription->getOption('label'));
304
    }
305
306
    public function testIfTrueNested(): void
307
    {
308
        $this->showMapper
309
            ->ifTrue(true)
310
                ->ifTrue(true)
311
                    ->add('fooName')
312
                ->ifEnd()
313
            ->ifEnd()
314
        ;
315
316
        $this->assertTrue($this->showMapper->has('fooName'));
317
    }
318
319
    public function testIfFalseNested(): void
320
    {
321
        $this->showMapper
322
            ->ifFalse(false)
323
                ->ifFalse(false)
324
                    ->add('fooName')
325
                ->ifEnd()
326
            ->ifEnd()
327
        ;
328
329
        $this->assertTrue($this->showMapper->has('fooName'));
330
    }
331
332
    public function testIfCombinationNested(): void
333
    {
334
        $this->showMapper
335
            ->ifTrue(true)
336
                ->ifFalse(false)
337
                    ->add('fooName')
338
                ->ifEnd()
339
            ->ifEnd()
340
        ;
341
342
        $this->assertTrue($this->showMapper->has('fooName'));
343
    }
344
345
    public function testIfFalseCombinationNested2(): void
346
    {
347
        $this->showMapper
348
            ->ifFalse(false)
349
                ->ifTrue(true)
350
                    ->add('fooName')
351
                ->ifEnd()
352
            ->ifEnd()
353
        ;
354
355
        $this->assertTrue($this->showMapper->has('fooName'));
356
    }
357
358
    public function testIfFalseCombinationNested3(): void
359
    {
360
        $this->showMapper
361
            ->ifFalse(true)
362
                ->ifTrue(false)
363
                    ->add('fooName')
364
                ->ifEnd()
365
            ->ifEnd()
366
        ;
367
368
        $this->assertFalse($this->showMapper->has('fooName'));
369
    }
370
371
    public function testIfFalseCombinationNested4(): void
372
    {
373
        $this->showMapper
374
            ->ifTrue(false)
375
                ->ifFalse(true)
376
                    ->add('fooName')
377
                ->ifEnd()
378
            ->ifEnd()
379
        ;
380
381
        $this->assertFalse($this->showMapper->has('fooName'));
382
    }
383
384
    public function testAddRemove(): void
385
    {
386
        $this->assertFalse($this->showMapper->has('fooName'));
387
388
        $fieldDescription = $this->getFieldDescriptionMock('fooName', 'fooLabel');
389
390
        $this->showMapper->add($fieldDescription);
391
        $this->assertTrue($this->showMapper->has('fooName'));
392
393
        $this->showMapper->remove('fooName');
394
        $this->assertFalse($this->showMapper->has('fooName'));
395
    }
396
397
    public function testAddException(): void
398
    {
399
        $this->expectException(\TypeError::class);
400
        $this->expectExceptionMessage('Unknown field name in show mapper. Field name should be either of FieldDescriptionInterface interface or string.');
401
402
        $this->showMapper->add(12345);
403
    }
404
405
    public function testAddDuplicateFieldNameException(): void
406
    {
407
        $name = 'name';
408
        $this->expectException(\LogicException::class);
409
        $this->expectExceptionMessage(
410
            sprintf('Duplicate field %s "name" in show mapper. Names should be unique.', $name)
411
        );
412
413
        $this->showMapper->add($name);
414
        $this->showMapper->add($name);
415
    }
416
417
    public function testKeys(): void
418
    {
419
        $fieldDescription1 = $this->getFieldDescriptionMock('fooName1', 'fooLabel1');
420
        $fieldDescription2 = $this->getFieldDescriptionMock('fooName2', 'fooLabel2');
421
422
        $this->showMapper->add($fieldDescription1);
423
        $this->showMapper->add($fieldDescription2);
424
425
        $this->assertSame(['fooName1', 'fooName2'], $this->showMapper->keys());
426
    }
427
428
    public function testReorder(): void
429
    {
430
        $this->assertSame([], $this->admin->getShowGroups());
431
432
        $fieldDescription1 = $this->getFieldDescriptionMock('fooName1', 'fooLabel1');
433
        $fieldDescription2 = $this->getFieldDescriptionMock('fooName2', 'fooLabel2');
434
        $fieldDescription3 = $this->getFieldDescriptionMock('fooName3', 'fooLabel3');
435
        $fieldDescription4 = $this->getFieldDescriptionMock('fooName4', 'fooLabel4');
436
437
        $this->showMapper->with('Group1');
438
        $this->showMapper->add($fieldDescription1);
439
        $this->showMapper->add($fieldDescription2);
440
        $this->showMapper->add($fieldDescription3);
441
        $this->showMapper->add($fieldDescription4);
442
443
        $this->assertSame([
444
            'Group1' => [
445
                'collapsed' => false,
446
                'class' => false,
447
                'description' => false,
448
                'label' => 'Group1',
449
                'translation_domain' => null,
450
                'name' => 'Group1',
451
                'box_class' => 'box box-primary',
452
                'empty_message' => 'message_form_group_empty',
453
                'empty_message_translation_domain' => 'SonataAdminBundle',
454
                'fields' => ['fooName1' => 'fooName1', 'fooName2' => 'fooName2', 'fooName3' => 'fooName3', 'fooName4' => 'fooName4'],
455
            ], ], $this->admin->getShowGroups());
456
457
        $this->showMapper->reorder(['fooName3', 'fooName2', 'fooName1', 'fooName4']);
458
459
        // print_r is used to compare order of items in associative arrays
460
        $this->assertSame(print_r([
461
            'Group1' => [
462
                'collapsed' => false,
463
                'class' => false,
464
                'description' => false,
465
                'label' => 'Group1',
466
                'translation_domain' => null,
467
                'name' => 'Group1',
468
                'box_class' => 'box box-primary',
469
                'empty_message' => 'message_form_group_empty',
470
                'empty_message_translation_domain' => 'SonataAdminBundle',
471
                'fields' => ['fooName3' => 'fooName3', 'fooName2' => 'fooName2', 'fooName1' => 'fooName1', 'fooName4' => 'fooName4'],
472
            ], ], true), print_r($this->admin->getShowGroups(), true));
473
    }
474
475
    public function testGroupRemovingWithoutTab(): void
476
    {
477
        $this->cleanShowMapper();
478
479
        $this->showMapper->with('groupfoo1');
480
        $this->showMapper->removeGroup('groupfoo1');
481
482
        $this->assertSame([], $this->admin->getShowGroups());
483
    }
484
485
    public function testGroupRemovingWithTab(): void
486
    {
487
        $this->cleanShowMapper();
488
489
        $this->showMapper->tab('mytab')->with('groupfoo2');
490
        $this->showMapper->removeGroup('groupfoo2', 'mytab');
491
492
        $this->assertSame([], $this->admin->getShowGroups());
493
    }
494
495
    public function testGroupRemovingWithoutTabAndWithTabRemoving(): void
496
    {
497
        $this->cleanShowMapper();
498
499
        $this->showMapper->with('groupfoo3');
500
        $this->showMapper->removeGroup('groupfoo3', 'default', true);
501
502
        $this->assertSame([], $this->admin->getShowGroups());
503
        $this->assertSame([], $this->admin->getShowTabs());
504
    }
505
506
    public function testGroupRemovingWithTabAndWithTabRemoving(): void
507
    {
508
        $this->cleanShowMapper();
509
510
        $this->showMapper->tab('mytab2')->with('groupfoo4');
511
        $this->showMapper->removeGroup('groupfoo4', 'mytab2', true);
512
513
        $this->assertSame([], $this->admin->getShowGroups());
514
        $this->assertSame([], $this->admin->getShowTabs());
515
    }
516
517
    public function testEmptyFieldLabel(): void
518
    {
519
        $this->showMapper->add('foo', null, ['label' => false]);
520
521
        $this->assertFalse($this->showMapper->get('foo')->getOption('label'));
522
523
        $this->showMapper->add('bar', null, ['label' => null]);
524
525
        $this->assertSame('bar', $this->showMapper->get('bar')->getOption('label'));
526
    }
527
528
    public function testAddOptionRole(): void
529
    {
530
        $this->cleanShowMapper();
531
532
        $this->showMapper->add('bar', 'bar');
533
534
        $this->assertTrue($this->showMapper->has('bar'));
535
536
        $this->showMapper->add('quux', 'bar', ['role' => 'ROLE_QUX']);
537
538
        $this->assertTrue($this->showMapper->has('bar'));
539
        $this->assertFalse($this->showMapper->has('quux'));
540
541
        $this->showMapper->end(); // Close default
542
543
        $this->showMapper
544
            ->with('qux')
545
                ->add('foobar', 'bar', ['role' => self::DEFAULT_GRANTED_ROLE])
546
                ->add('foo', 'bar', ['role' => 'ROLE_QUX'])
547
                ->add('baz', 'bar')
548
            ->end();
549
550
        $this->assertArrayHasKey('qux', $this->admin->getShowGroups());
551
        $this->assertTrue($this->showMapper->has('foobar'));
552
        $this->assertFalse($this->showMapper->has('foo'));
553
        $this->assertTrue($this->showMapper->has('baz'));
554
    }
555
556
    private function cleanShowMapper(): void
557
    {
558
        $this->showBuilder = $this->getMockForAbstractClass(ShowBuilderInterface::class);
559
        $this->showBuilder
560
            ->method('addField')
561
            ->willReturnCallback(static function (FieldDescriptionCollection $list, ?string $type, FieldDescriptionInterface $fieldDescription, AdminInterface $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...
562
                $list->add($fieldDescription);
563
            });
564
        $this->fieldDescriptionCollection = new FieldDescriptionCollection();
565
        $this->admin = new CleanAdmin('code', 'class', 'controller');
566
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
567
        $securityHandler
568
            ->method('isGranted')
569
            ->willReturnCallback(static function (AdminInterface $admin, string $attributes, $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...
570
                return self::DEFAULT_GRANTED_ROLE === $attributes;
571
            });
572
573
        $this->admin->setSecurityHandler($securityHandler);
574
575
        $this->showMapper = new ShowMapper($this->showBuilder, $this->fieldDescriptionCollection, $this->admin);
576
577
        $modelManager = $this->getMockForAbstractClass(ModelManagerInterface::class);
578
579
        $modelManager
580
            ->method('getNewFieldDescriptionInstance')
581
            ->willReturnCallback(function (string $class, string $name, array $options = []): FieldDescriptionInterface {
582
                $fieldDescription = $this->getFieldDescriptionMock();
583
                $fieldDescription->setName($name);
584
                $fieldDescription->setOptions($options);
585
586
                return $fieldDescription;
587
            });
588
589
        $this->admin->setModelManager($modelManager);
590
        $this->admin->setLabelTranslatorStrategy(new NoopLabelTranslatorStrategy());
591
592
        $this->admin->setShowBuilder(new ShowBuilder());
593
    }
594
595
    private function getFieldDescriptionMock(?string $name = null, ?string $label = null): BaseFieldDescription
596
    {
597
        $fieldDescription = $this->getMockForAbstractClass(BaseFieldDescription::class);
598
599
        if (null !== $name) {
600
            $fieldDescription->setName($name);
601
        }
602
603
        if (null !== $label) {
604
            $fieldDescription->setOption('label', $label);
605
        }
606
607
        return $fieldDescription;
608
    }
609
}
610