Completed
Push — master ( a4094f...b681a2 )
by Grégoire
16s queued 12s
created

AdminTest::testIsGranted()   B

Complexity

Conditions 5
Paths 1

Size

Total Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 54
rs 8.6925
c 0
b 0
f 0
cc 5
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
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\Admin;
15
16
use Doctrine\Common\Collections\Collection;
17
use Knp\Menu\FactoryInterface;
18
use Knp\Menu\ItemInterface;
19
use PHPUnit\Framework\TestCase;
20
use Sonata\AdminBundle\Admin\AbstractAdmin;
21
use Sonata\AdminBundle\Admin\AbstractAdminExtension;
22
use Sonata\AdminBundle\Admin\AdminExtensionInterface;
23
use Sonata\AdminBundle\Admin\AdminInterface;
24
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
25
use Sonata\AdminBundle\Admin\Pool;
26
use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
27
use Sonata\AdminBundle\Builder\FormContractorInterface;
28
use Sonata\AdminBundle\Builder\ListBuilderInterface;
29
use Sonata\AdminBundle\Builder\RouteBuilderInterface;
30
use Sonata\AdminBundle\Builder\ShowBuilderInterface;
31
use Sonata\AdminBundle\Datagrid\DatagridInterface;
32
use Sonata\AdminBundle\Datagrid\PagerInterface;
33
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
34
use Sonata\AdminBundle\Filter\Persister\FilterPersisterInterface;
35
use Sonata\AdminBundle\Model\AuditManagerInterface;
36
use Sonata\AdminBundle\Model\ModelManagerInterface;
37
use Sonata\AdminBundle\Route\DefaultRouteGenerator;
38
use Sonata\AdminBundle\Route\PathInfoBuilder;
39
use Sonata\AdminBundle\Route\RouteGeneratorInterface;
40
use Sonata\AdminBundle\Route\RoutesCache;
41
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
42
use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface;
43
use Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface;
44
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentAdmin;
45
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentVoteAdmin;
46
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentWithCustomRouteAdmin;
47
use Sonata\AdminBundle\Tests\Fixtures\Admin\FieldDescription;
48
use Sonata\AdminBundle\Tests\Fixtures\Admin\FilteredAdmin;
49
use Sonata\AdminBundle\Tests\Fixtures\Admin\ModelAdmin;
50
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin;
51
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostWithCustomRouteAdmin;
52
use Sonata\AdminBundle\Tests\Fixtures\Admin\TagAdmin;
53
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\BlogPost;
54
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment;
55
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Post;
56
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Tag;
57
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
58
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToStringNull;
59
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
60
use Sonata\Doctrine\Adapter\AdapterInterface;
61
use Symfony\Component\DependencyInjection\Container;
62
use Symfony\Component\Filesystem\Filesystem;
63
use Symfony\Component\Form\FormBuilder;
64
use Symfony\Component\Form\FormBuilderInterface;
65
use Symfony\Component\Form\FormEvent;
66
use Symfony\Component\Form\FormEvents;
67
use Symfony\Component\HttpFoundation\ParameterBag;
68
use Symfony\Component\HttpFoundation\Request;
69
use Symfony\Component\PropertyAccess\PropertyAccess;
70
use Symfony\Component\Routing\RouterInterface;
71
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
72
use Symfony\Component\Translation\TranslatorInterface;
73
use Symfony\Component\Validator\Mapping\MemberMetadata;
74
use Symfony\Component\Validator\Validator\ValidatorInterface;
75
76
class AdminTest extends TestCase
77
{
78
    protected $cacheTempFolder;
79
80
    protected function setUp(): void
81
    {
82
        $this->cacheTempFolder = sys_get_temp_dir().'/sonata_test_route';
83
        $filesystem = new Filesystem();
84
        $filesystem->remove($this->cacheTempFolder);
85
    }
86
87
    /**
88
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::__construct
89
     */
90
    public function testConstructor(): void
91
    {
92
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
93
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
94
95
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
96
        $this->assertInstanceOf(AbstractAdmin::class, $admin);
97
        $this->assertSame($class, $admin->getClass());
98
        $this->assertSame($baseControllerName, $admin->getBaseControllerName());
99
    }
100
101
    public function testGetClass(): void
102
    {
103
        $class = Post::class;
104
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
105
106
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
107
108
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
109
110
        $admin->setSubject(new BlogPost());
111
        $this->assertSame(BlogPost::class, $admin->getClass());
112
113
        $admin->setSubClasses(['foo']);
114
        $this->assertSame(BlogPost::class, $admin->getClass());
115
116
        $admin->setSubject(null);
117
        $admin->setSubClasses([]);
118
        $this->assertSame($class, $admin->getClass());
119
120
        $admin->setSubClasses(['foo' => 'bar']);
121
        $admin->setRequest(new Request(['subclass' => 'foo']));
122
        $this->assertSame('bar', $admin->getClass());
123
    }
124
125
    public function testGetClassException(): void
126
    {
127
        $this->expectException(\RuntimeException::class);
128
        $this->expectExceptionMessage('Feature not implemented: an embedded admin cannot have subclass');
129
130
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
131
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
132
133
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
134
        $admin->setParentFieldDescription(new FieldDescription());
135
        $admin->setSubClasses(['foo' => 'bar']);
136
        $admin->setRequest(new Request(['subclass' => 'foo']));
137
        $admin->getClass();
138
    }
139
140
    public function testCheckAccessThrowsExceptionOnMadeUpAction(): void
141
    {
142
        $admin = new PostAdmin(
143
            'sonata.post.admin.post',
144
            'Application\Sonata\NewsBundle\Entity\Post',
145
            'Sonata\NewsBundle\Controller\PostAdminController'
146
        );
147
        $this->expectException(
148
            \InvalidArgumentException::class
149
        );
150
        $this->expectExceptionMessage(
151
            'Action "made-up" could not be found'
152
        );
153
        $admin->checkAccess('made-up');
154
    }
155
156
    public function testCheckAccessThrowsAccessDeniedException(): void
157
    {
158
        $admin = new PostAdmin(
159
            'sonata.post.admin.post',
160
            'Application\Sonata\NewsBundle\Entity\Post',
161
            'Sonata\NewsBundle\Controller\PostAdminController'
162
        );
163
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
164
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
165
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
166
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
167
        $customExtension->getAccessMapping($admin)->willReturn(
168
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
169
        );
170
        $admin->addExtension($customExtension->reveal());
171
        $admin->setSecurityHandler($securityHandler->reveal());
172
        $this->expectException(
173
            AccessDeniedException::class
174
        );
175
        $this->expectExceptionMessage(
176
            'Access Denied to the action custom_action and role EXTRA_CUSTOM_ROLE'
177
        );
178
        $admin->checkAccess('custom_action');
179
    }
180
181
    public function testHasAccessOnMadeUpAction(): void
182
    {
183
        $admin = new PostAdmin(
184
            'sonata.post.admin.post',
185
            'Application\Sonata\NewsBundle\Entity\Post',
186
            'Sonata\NewsBundle\Controller\PostAdminController'
187
        );
188
189
        $this->assertFalse($admin->hasAccess('made-up'));
190
    }
191
192
    public function testHasAccess(): void
193
    {
194
        $admin = new PostAdmin(
195
            'sonata.post.admin.post',
196
            'Application\Sonata\NewsBundle\Entity\Post',
197
            'Sonata\NewsBundle\Controller\PostAdminController'
198
        );
199
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
200
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
201
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
202
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
203
        $customExtension->getAccessMapping($admin)->willReturn(
204
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
205
        );
206
        $admin->addExtension($customExtension->reveal());
207
        $admin->setSecurityHandler($securityHandler->reveal());
208
209
        $this->assertFalse($admin->hasAccess('custom_action'));
210
    }
211
212
    public function testHasAccessAllowsAccess(): void
213
    {
214
        $admin = new PostAdmin(
215
            'sonata.post.admin.post',
216
            'Application\Sonata\NewsBundle\Entity\Post',
217
            'Sonata\NewsBundle\Controller\PostAdminController'
218
        );
219
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
220
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
221
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(true);
222
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
223
        $customExtension->getAccessMapping($admin)->willReturn(
224
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
225
        );
226
        $admin->addExtension($customExtension->reveal());
227
        $admin->setSecurityHandler($securityHandler->reveal());
228
229
        $this->assertTrue($admin->hasAccess('custom_action'));
230
    }
231
232
    public function testHasAccessAllowsAccessEditAction(): void
233
    {
234
        $admin = new PostAdmin(
235
            'sonata.post.admin.post',
236
            'Application\Sonata\NewsBundle\Entity\Post',
237
            'Sonata\NewsBundle\Controller\PostAdminController'
238
        );
239
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
240
        $securityHandler->isGranted($admin, 'EDIT_ROLE', $admin)->willReturn(true);
241
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
242
        $customExtension->getAccessMapping($admin)->willReturn(
243
            ['edit_action' => ['EDIT_ROLE']]
244
        );
245
        $admin->addExtension($customExtension->reveal());
246
        $admin->setSecurityHandler($securityHandler->reveal());
247
248
        $this->assertTrue($admin->hasAccess('edit_action'));
249
    }
250
251
    /**
252
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChild
253
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::addChild
254
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChild
255
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::isChild
256
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChildren
257
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChildren
258
     */
259
    public function testChildren(): void
260
    {
261
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
262
        $this->assertFalse($postAdmin->hasChildren());
263
        $this->assertFalse($postAdmin->hasChild('comment'));
264
265
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
266
        $postAdmin->addChild($commentAdmin, 'post');
267
268
        $this->assertTrue($postAdmin->hasChildren());
269
        $this->assertTrue($postAdmin->hasChild('sonata.post.admin.comment'));
270
271
        $this->assertSame('sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getCode());
272
        $this->assertSame('sonata.post.admin.post|sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getBaseCodeRoute());
273
        $this->assertSame($postAdmin, $postAdmin->getChild('sonata.post.admin.comment')->getParent());
274
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
275
276
        $this->assertFalse($postAdmin->isChild());
277
        $this->assertTrue($commentAdmin->isChild());
278
279
        $this->assertSame(['sonata.post.admin.comment' => $commentAdmin], $postAdmin->getChildren());
280
    }
281
282
    /**
283
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configure
284
     */
285
    public function testConfigure(): void
286
    {
287
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
288
        $this->assertNotNull($admin->getUniqid());
289
290
        $admin->initialize();
291
        $this->assertNotNull($admin->getUniqid());
292
        $this->assertSame('Post', $admin->getClassnameLabel());
293
294
        $admin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
295
        $admin->setClassnameLabel('postcomment');
296
297
        $admin->initialize();
298
        $this->assertSame('postcomment', $admin->getClassnameLabel());
299
    }
300
301
    public function testConfigureWithValidParentAssociationMapping(): void
302
    {
303
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
304
        $admin->setParentAssociationMapping('Category');
305
306
        $admin->initialize();
307
        $this->assertSame('Category', $admin->getParentAssociationMapping());
308
    }
309
310
    public function provideGetBaseRoutePattern()
311
    {
312
        return [
313
            [
314
                'Application\Sonata\NewsBundle\Entity\Post',
315
                '/sonata/news/post',
316
            ],
317
            [
318
                'Application\Sonata\NewsBundle\Document\Post',
319
                '/sonata/news/post',
320
            ],
321
            [
322
                'MyApplication\MyBundle\Entity\Post',
323
                '/myapplication/my/post',
324
            ],
325
            [
326
                'MyApplication\MyBundle\Entity\Post\Category',
327
                '/myapplication/my/post-category',
328
            ],
329
            [
330
                'MyApplication\MyBundle\Entity\Product\Category',
331
                '/myapplication/my/product-category',
332
            ],
333
            [
334
                'MyApplication\MyBundle\Entity\Other\Product\Category',
335
                '/myapplication/my/other-product-category',
336
            ],
337
            [
338
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
339
                '/cmf/foo/menu',
340
            ],
341
            [
342
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
343
                '/cmf/foo/menu',
344
            ],
345
            [
346
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
347
                '/symfony/barbar/menu',
348
            ],
349
            [
350
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
351
                '/symfony/barbar/menu-item',
352
            ],
353
            [
354
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
355
                '/cmf/foo/menu',
356
            ],
357
            [
358
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
359
                '/cmf/foo/menu',
360
            ],
361
            [
362
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
363
                '/cmf/foo/menu',
364
            ],
365
            [
366
                'AppBundle\Entity\User',
367
                '/app/user',
368
            ],
369
            [
370
                'App\Entity\User',
371
                '/app/user',
372
            ],
373
        ];
374
    }
375
376
    /**
377
     * @dataProvider provideGetBaseRoutePattern
378
     */
379
    public function testGetBaseRoutePattern(string $objFqn, string $expected): void
380
    {
381
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
382
        $this->assertSame($expected, $admin->getBaseRoutePattern());
383
    }
384
385
    /**
386
     * @dataProvider provideGetBaseRoutePattern
387
     */
388
    public function testGetBaseRoutePatternWithChildAdmin(string $objFqn, string $expected): void
389
    {
390
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
391
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
392
        $commentAdmin->setParent($postAdmin);
393
394
        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
395
    }
396
397
    /**
398
     * @dataProvider provideGetBaseRoutePattern
399
     */
400
    public function testGetBaseRoutePatternWithTwoNestedChildAdmin(string $objFqn, string $expected): void
401
    {
402
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
403
        $commentAdmin = new CommentAdmin(
404
            'sonata.post.admin.comment',
405
            'Application\Sonata\NewsBundle\Entity\Comment',
406
            'Sonata\NewsBundle\Controller\CommentAdminController'
407
        );
408
        $commentVoteAdmin = new CommentVoteAdmin(
409
            'sonata.post.admin.comment_vote',
410
            'Application\Sonata\NewsBundle\Entity\CommentVote',
411
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
412
        );
413
        $commentAdmin->setParent($postAdmin);
414
        $commentVoteAdmin->setParent($commentAdmin);
415
416
        $this->assertSame($expected.'/{id}/comment/{childId}/commentvote', $commentVoteAdmin->getBaseRoutePattern());
417
    }
418
419
    public function testGetBaseRoutePatternWithSpecifedPattern(): void
420
    {
421
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostWithCustomRouteAdminController');
422
423
        $this->assertSame('/post-custom', $postAdmin->getBaseRoutePattern());
424
    }
425
426
    public function testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern(): void
427
    {
428
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
429
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
430
        $commentAdmin->setParent($postAdmin);
431
432
        $this->assertSame('/sonata/news/post/{id}/comment-custom', $commentAdmin->getBaseRoutePattern());
433
    }
434
435
    public function testGetBaseRoutePatternWithUnreconizedClassname(): void
436
    {
437
        $this->expectException(\RuntimeException::class);
438
439
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
440
        $admin->getBaseRoutePattern();
441
    }
442
443
    public function provideGetBaseRouteName()
444
    {
445
        return [
446
            [
447
                'Application\Sonata\NewsBundle\Entity\Post',
448
                'admin_sonata_news_post',
449
            ],
450
            [
451
                'Application\Sonata\NewsBundle\Document\Post',
452
                'admin_sonata_news_post',
453
            ],
454
            [
455
                'MyApplication\MyBundle\Entity\Post',
456
                'admin_myapplication_my_post',
457
            ],
458
            [
459
                'MyApplication\MyBundle\Entity\Post\Category',
460
                'admin_myapplication_my_post_category',
461
            ],
462
            [
463
                'MyApplication\MyBundle\Entity\Product\Category',
464
                'admin_myapplication_my_product_category',
465
            ],
466
            [
467
                'MyApplication\MyBundle\Entity\Other\Product\Category',
468
                'admin_myapplication_my_other_product_category',
469
            ],
470
            [
471
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
472
                'admin_cmf_foo_menu',
473
            ],
474
            [
475
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
476
                'admin_cmf_foo_menu',
477
            ],
478
            [
479
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
480
                'admin_symfony_barbar_menu',
481
            ],
482
            [
483
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
484
                'admin_symfony_barbar_menu_item',
485
            ],
486
            [
487
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
488
                'admin_cmf_foo_menu',
489
            ],
490
            [
491
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
492
                'admin_cmf_foo_menu',
493
            ],
494
            [
495
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
496
                'admin_cmf_foo_menu',
497
            ],
498
            [
499
                'AppBundle\Entity\User',
500
                'admin_app_user',
501
            ],
502
            [
503
                'App\Entity\User',
504
                'admin_app_user',
505
            ],
506
        ];
507
    }
508
509
    /**
510
     * @dataProvider provideGetBaseRouteName
511
     */
512
    public function testGetBaseRouteName(string $objFqn, string $expected): void
513
    {
514
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
515
516
        $this->assertSame($expected, $admin->getBaseRouteName());
517
    }
518
519
    /**
520
     * @group legacy
521
     * @expectedDeprecation Calling "addChild" without second argument is deprecated since sonata-project/admin-bundle 3.35 and will not be allowed in 4.0.
522
     * @dataProvider provideGetBaseRouteName
523
     */
524
    public function testGetBaseRouteNameWithChildAdmin(string $objFqn, string $expected): void
525
    {
526
        $routeGenerator = new DefaultRouteGenerator(
527
            $this->createMock(RouterInterface::class),
528
            new RoutesCache($this->cacheTempFolder, true)
529
        );
530
531
        $container = new Container();
532
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
533
534
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
535
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
536
        $container->set('sonata.post.admin.post', $postAdmin);
537
        $postAdmin->setConfigurationPool($pool);
538
        $postAdmin->setRouteBuilder($pathInfo);
539
        $postAdmin->setRouteGenerator($routeGenerator);
540
        $postAdmin->initialize();
541
542
        $commentAdmin = new CommentAdmin(
543
            'sonata.post.admin.comment',
544
            'Application\Sonata\NewsBundle\Entity\Comment',
545
            'Sonata\NewsBundle\Controller\CommentAdminController'
546
        );
547
        $container->set('sonata.post.admin.comment', $commentAdmin);
548
        $commentAdmin->setConfigurationPool($pool);
549
        $commentAdmin->setRouteBuilder($pathInfo);
550
        $commentAdmin->setRouteGenerator($routeGenerator);
551
        $commentAdmin->initialize();
552
553
        $postAdmin->addChild($commentAdmin, 'post');
554
555
        $commentVoteAdmin = new CommentVoteAdmin(
556
            'sonata.post.admin.comment_vote',
557
            'Application\Sonata\NewsBundle\Entity\CommentVote',
558
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
559
        );
560
561
        $container->set('sonata.post.admin.comment_vote', $commentVoteAdmin);
562
        $commentVoteAdmin->setConfigurationPool($pool);
563
        $commentVoteAdmin->setRouteBuilder($pathInfo);
564
        $commentVoteAdmin->setRouteGenerator($routeGenerator);
565
        $commentVoteAdmin->initialize();
566
567
        $commentAdmin->addChild($commentVoteAdmin);
568
        $pool->setAdminServiceIds([
569
            'sonata.post.admin.post',
570
            'sonata.post.admin.comment',
571
            'sonata.post.admin.comment_vote',
572
        ]);
573
574
        $this->assertSame($expected.'_comment', $commentAdmin->getBaseRouteName());
575
576
        $this->assertTrue($postAdmin->hasRoute('show'));
577
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
578
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.show'));
579
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment|sonata.post.admin.comment_vote.show'));
580
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment.list'));
581
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment|sonata.post.admin.comment_vote.list'));
582
        $this->assertFalse($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.edit'));
583
        $this->assertFalse($commentAdmin->hasRoute('edit'));
584
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
585
586
        /*
587
         * Test the route name from request
588
         */
589
        $postListRequest = new Request(
590
            [],
591
            [],
592
            [
593
                '_route' => $postAdmin->getBaseRouteName().'_list',
594
            ]
595
        );
596
597
        $postAdmin->setRequest($postListRequest);
598
        $commentAdmin->setRequest($postListRequest);
599
600
        $this->assertTrue($postAdmin->isCurrentRoute('list'));
601
        $this->assertFalse($postAdmin->isCurrentRoute('create'));
602
        $this->assertFalse($commentAdmin->isCurrentRoute('list'));
603
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('list'));
604
        $this->assertTrue($commentAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
605
        $this->assertFalse($commentAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
606
        $this->assertTrue($commentVoteAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
607
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
608
    }
609
610
    public function testGetBaseRouteNameWithUnreconizedClassname(): void
611
    {
612
        $this->expectException(\RuntimeException::class);
613
614
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
615
        $admin->getBaseRouteName();
616
    }
617
618
    public function testGetBaseRouteNameWithSpecifiedName(): void
619
    {
620
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
621
622
        $this->assertSame('post_custom', $postAdmin->getBaseRouteName());
623
    }
624
625
    public function testGetBaseRouteNameWithChildAdminAndWithSpecifiedName(): void
626
    {
627
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
628
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
629
        $commentAdmin->setParent($postAdmin);
630
631
        $this->assertSame('admin_sonata_news_post_comment_custom', $commentAdmin->getBaseRouteName());
632
    }
633
634
    public function testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName(): void
635
    {
636
        $postAdmin = new PostAdmin(
637
            'sonata.post.admin.post',
638
            'Application\Sonata\NewsBundle\Entity\Post',
639
            'Sonata\NewsBundle\Controller\PostAdminController'
640
        );
641
        $commentAdmin = new CommentWithCustomRouteAdmin(
642
            'sonata.post.admin.comment_with_custom_route',
643
            'Application\Sonata\NewsBundle\Entity\Comment',
644
            'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController'
645
        );
646
        $commentVoteAdmin = new CommentVoteAdmin(
647
            'sonata.post.admin.comment_vote',
648
            'Application\Sonata\NewsBundle\Entity\CommentVote',
649
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
650
        );
651
        $commentAdmin->setParent($postAdmin);
652
        $commentVoteAdmin->setParent($commentAdmin);
653
654
        $this->assertSame('admin_sonata_news_post_comment_custom_commentvote', $commentVoteAdmin->getBaseRouteName());
655
    }
656
657
    /**
658
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setUniqid
659
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getUniqid
660
     */
661
    public function testSetUniqid(): void
662
    {
663
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
664
665
        $uniqid = uniqid();
666
        $admin->setUniqid($uniqid);
667
668
        $this->assertSame($uniqid, $admin->getUniqid());
669
    }
670
671
    public function testToString(): void
672
    {
673
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
674
675
        $s = new \stdClass();
676
677
        $this->assertNotEmpty($admin->toString($s));
678
679
        $s = new FooToString();
680
        $this->assertSame('salut', $admin->toString($s));
681
682
        // To string method is implemented, but returns null
683
        $s = new FooToStringNull();
684
        $this->assertNotEmpty($admin->toString($s));
685
686
        $this->assertSame('', $admin->toString(false));
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a object.

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...
687
    }
688
689
    public function testIsAclEnabled(): void
690
    {
691
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
692
693
        $this->assertFalse($postAdmin->isAclEnabled());
694
695
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
696
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
697
        $this->assertTrue($commentAdmin->isAclEnabled());
698
    }
699
700
    /**
701
     * @group legacy
702
     *
703
     * @expectedDeprecation Calling Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode() when there is no active subclass is deprecated since sonata-project/admin-bundle 3.52 and will throw an exception in 4.0. Use Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass() to know if there is an active subclass.
704
     *
705
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
706
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
707
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
708
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
709
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
710
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
711
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
712
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
713
     */
714
    public function testSubClass(): void
715
    {
716
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
717
        $admin = new PostAdmin(
718
            'sonata.post.admin.post',
719
            Post::class,
720
            'Sonata\NewsBundle\Controller\PostAdminController'
721
        );
722
        $this->assertFalse($admin->hasSubClass('test'));
723
        $this->assertFalse($admin->hasActiveSubClass());
724
        $this->assertCount(0, $admin->getSubClasses());
725
        $this->assertNull($admin->getActiveSubClass());
726
        $this->assertNull($admin->getActiveSubclassCode());
727
        $this->assertSame(Post::class, $admin->getClass());
728
729
        // Just for the record, if there is no inheritance set, the getSubject is not used
730
        // the getSubject can also lead to some issue
731
        $admin->setSubject(new BlogPost());
732
        $this->assertSame(BlogPost::class, $admin->getClass());
733
734
        $admin->setSubClasses([
735
            'extended1' => 'NewsBundle\Entity\PostExtended1',
736
            'extended2' => 'NewsBundle\Entity\PostExtended2',
737
        ]);
738
        $this->assertFalse($admin->hasSubClass('test'));
739
        $this->assertTrue($admin->hasSubClass('extended1'));
740
        $this->assertFalse($admin->hasActiveSubClass());
741
        $this->assertCount(2, $admin->getSubClasses());
742
        // NEXT_MAJOR: remove the following 2 `assertNull()` assertions
743
        $this->assertNull($admin->getActiveSubClass());
744
        $this->assertNull($admin->getActiveSubclassCode());
745
        $this->assertSame(
746
            BlogPost::class,
747
            $admin->getClass(),
748
            'When there is no subclass in the query the class parameter should be returned'
749
        );
750
751
        $request = new Request(['subclass' => 'extended1']);
752
        $admin->setRequest($request);
753
        $this->assertFalse($admin->hasSubClass('test'));
754
        $this->assertTrue($admin->hasSubClass('extended1'));
755
        $this->assertTrue($admin->hasActiveSubClass());
756
        $this->assertCount(2, $admin->getSubClasses());
757
        $this->assertSame(
758
            'NewsBundle\Entity\PostExtended1',
759
            $admin->getActiveSubClass(),
760
            'It should return the curently active sub class.'
761
        );
762
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
763
        $this->assertSame(
764
            'NewsBundle\Entity\PostExtended1',
765
            $admin->getClass(),
766
            'getClass() should return the name of the sub class when passed through a request query parameter.'
767
        );
768
769
        $request->query->set('subclass', 'inject');
770
771
        $this->assertNull($admin->getActiveSubclassCode());
772
        // NEXT_MAJOR: remove the previous `assertNull()` assertion and uncomment the following lines
773
        // $this->expectException(\LogicException::class);
774
        // $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
775
    }
776
777
    /**
778
     * @group legacy
779
     *
780
     * @expectedDeprecation Calling Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode() when there is no active subclass is deprecated since sonata-project/admin-bundle 3.52 and will throw an exception in 4.0. Use Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass() to know if there is an active subclass.
781
     */
782
    public function testNonExistantSubclass(): void
783
    {
784
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
785
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
786
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
787
788
        $admin->setRequest(new Request(['subclass' => 'inject']));
789
790
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
791
792
        $this->assertTrue($admin->hasActiveSubClass());
793
794
        $this->expectException(\RuntimeException::class);
795
796
        $admin->getActiveSubClass();
797
    }
798
799
    /**
800
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
801
     */
802
    public function testOnlyOneSubclassNeededToBeActive(): void
803
    {
804
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
805
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
806
        $request = new Request(['subclass' => 'extended1']);
807
        $admin->setRequest($request);
808
        $this->assertTrue($admin->hasActiveSubClass());
809
    }
810
811
    /**
812
     * @group legacy
813
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since sonata-project/admin-bundle 3.30 and will be removed in 4.0.
814
     */
815
    public function testAddSubClassIsDeprecated(): void
816
    {
817
        $admin = new PostAdmin(
818
            'sonata.post.admin.post',
819
            Post::class,
820
            'Sonata\NewsBundle\Controller\PostAdminController'
821
        );
822
        $admin->addSubClass('whatever');
823
    }
824
825
    public function testGetPerPageOptions(): void
826
    {
827
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
828
829
        $perPageOptions = $admin->getPerPageOptions();
830
831
        foreach ($perPageOptions as $perPage) {
832
            $this->assertSame(0, $perPage % 4);
833
        }
834
835
        $admin->setPerPageOptions([500, 1000]);
836
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
837
    }
838
839
    public function testGetLabelTranslatorStrategy(): void
840
    {
841
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
842
843
        $this->assertNull($admin->getLabelTranslatorStrategy());
844
845
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
846
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
847
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
848
    }
849
850
    public function testGetRouteBuilder(): void
851
    {
852
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
853
854
        $this->assertNull($admin->getRouteBuilder());
855
856
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
857
        $admin->setRouteBuilder($routeBuilder);
858
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
859
    }
860
861
    public function testGetMenuFactory(): void
862
    {
863
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
864
865
        $this->assertNull($admin->getMenuFactory());
866
867
        $menuFactory = $this->createMock(FactoryInterface::class);
868
        $admin->setMenuFactory($menuFactory);
869
        $this->assertSame($menuFactory, $admin->getMenuFactory());
870
    }
871
872
    public function testGetExtensions(): void
873
    {
874
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
875
876
        $this->assertSame([], $admin->getExtensions());
877
878
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
879
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
880
881
        $admin->addExtension($adminExtension1);
882
        $admin->addExtension($adminExtension2);
883
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
884
    }
885
886
    public function testGetFilterTheme(): void
887
    {
888
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
889
890
        $this->assertSame([], $admin->getFilterTheme());
891
892
        $admin->setFilterTheme(['FooTheme']);
893
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
894
    }
895
896
    public function testGetFormTheme(): void
897
    {
898
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
899
900
        $this->assertSame([], $admin->getFormTheme());
901
902
        $admin->setFormTheme(['FooTheme']);
903
904
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
905
    }
906
907
    public function testGetValidator(): void
908
    {
909
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
910
911
        $this->assertNull($admin->getValidator());
912
913
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
914
915
        $admin->setValidator($validator);
916
        $this->assertSame($validator, $admin->getValidator());
917
    }
918
919
    public function testGetSecurityHandler(): void
920
    {
921
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
922
923
        $this->assertNull($admin->getSecurityHandler());
924
925
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
926
        $admin->setSecurityHandler($securityHandler);
927
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
928
    }
929
930
    public function testGetSecurityInformation(): void
931
    {
932
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
933
934
        $this->assertSame([], $admin->getSecurityInformation());
935
936
        $securityInformation = [
937
            'GUEST' => ['VIEW', 'LIST'],
938
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
939
        ];
940
941
        $admin->setSecurityInformation($securityInformation);
942
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
943
    }
944
945
    public function testGetManagerType(): void
946
    {
947
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
948
949
        $this->assertNull($admin->getManagerType());
950
951
        $admin->setManagerType('foo_orm');
952
        $this->assertSame('foo_orm', $admin->getManagerType());
953
    }
954
955
    public function testGetModelManager(): void
956
    {
957
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
958
959
        $this->assertNull($admin->getModelManager());
960
961
        $modelManager = $this->createMock(ModelManagerInterface::class);
962
963
        $admin->setModelManager($modelManager);
964
        $this->assertSame($modelManager, $admin->getModelManager());
965
    }
966
967
    public function testGetBaseCodeRoute(): void
968
    {
969
        $postAdmin = new PostAdmin(
970
            'sonata.post.admin.post',
971
            'NewsBundle\Entity\Post',
972
            'Sonata\NewsBundle\Controller\PostAdminController'
973
        );
974
        $commentAdmin = new CommentAdmin(
975
            'sonata.post.admin.comment',
976
            'Application\Sonata\NewsBundle\Entity\Comment',
977
            'Sonata\NewsBundle\Controller\CommentAdminController'
978
        );
979
980
        $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
981
982
        $postAdmin->addChild($commentAdmin, 'post');
983
984
        $this->assertSame(
985
            'sonata.post.admin.post|sonata.post.admin.comment',
986
            $commentAdmin->getBaseCodeRoute()
987
        );
988
    }
989
990
    public function testGetRouteGenerator(): void
991
    {
992
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
993
994
        $this->assertNull($admin->getRouteGenerator());
995
996
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
997
998
        $admin->setRouteGenerator($routeGenerator);
999
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1000
    }
1001
1002
    public function testGetConfigurationPool(): void
1003
    {
1004
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1005
1006
        $this->assertNull($admin->getConfigurationPool());
1007
1008
        $pool = $this->getMockBuilder(Pool::class)
1009
            ->disableOriginalConstructor()
1010
            ->getMock();
1011
1012
        $admin->setConfigurationPool($pool);
1013
        $this->assertSame($pool, $admin->getConfigurationPool());
1014
    }
1015
1016
    public function testGetShowBuilder(): void
1017
    {
1018
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1019
1020
        $this->assertNull($admin->getShowBuilder());
1021
1022
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1023
1024
        $admin->setShowBuilder($showBuilder);
1025
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1026
    }
1027
1028
    public function testGetListBuilder(): void
1029
    {
1030
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1031
1032
        $this->assertNull($admin->getListBuilder());
1033
1034
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1035
1036
        $admin->setListBuilder($listBuilder);
1037
        $this->assertSame($listBuilder, $admin->getListBuilder());
1038
    }
1039
1040
    public function testGetDatagridBuilder(): void
1041
    {
1042
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1043
1044
        $this->assertNull($admin->getDatagridBuilder());
1045
1046
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1047
1048
        $admin->setDatagridBuilder($datagridBuilder);
1049
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1050
    }
1051
1052
    public function testGetFormContractor(): void
1053
    {
1054
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1055
1056
        $this->assertNull($admin->getFormContractor());
1057
1058
        $formContractor = $this->createMock(FormContractorInterface::class);
1059
1060
        $admin->setFormContractor($formContractor);
1061
        $this->assertSame($formContractor, $admin->getFormContractor());
1062
    }
1063
1064
    public function testGetRequest(): void
1065
    {
1066
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1067
1068
        $this->assertFalse($admin->hasRequest());
1069
1070
        $request = new Request();
1071
1072
        $admin->setRequest($request);
1073
        $this->assertSame($request, $admin->getRequest());
1074
        $this->assertTrue($admin->hasRequest());
1075
    }
1076
1077
    public function testGetRequestWithException(): void
1078
    {
1079
        $this->expectException(\RuntimeException::class);
1080
        $this->expectExceptionMessage('The Request object has not been set');
1081
1082
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1083
        $admin->getRequest();
1084
    }
1085
1086
    public function testGetTranslationDomain(): void
1087
    {
1088
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1089
1090
        $this->assertSame('messages', $admin->getTranslationDomain());
1091
1092
        $admin->setTranslationDomain('foo');
1093
        $this->assertSame('foo', $admin->getTranslationDomain());
1094
    }
1095
1096
    /**
1097
     * @group legacy
1098
     */
1099
    public function testGetTranslator(): void
1100
    {
1101
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1102
1103
        $this->assertNull($admin->getTranslator());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::getTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1104
1105
        $translator = $this->createMock(TranslatorInterface::class);
1106
1107
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1108
        $this->assertSame($translator, $admin->getTranslator());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::getTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1109
    }
1110
1111
    public function testGetShowGroups(): void
1112
    {
1113
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1114
1115
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1116
        $this->assertFalse($admin->getShowGroups('sonata_deprecation_mute'));
1117
1118
        $groups = ['foo', 'bar', 'baz'];
1119
1120
        $admin->setShowGroups($groups);
1121
        $this->assertSame($groups, $admin->getShowGroups());
1122
    }
1123
1124
    public function testGetFormGroups(): void
1125
    {
1126
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1127
1128
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1129
        $this->assertFalse($admin->getFormGroups('sonata_deprecation_mute'));
1130
1131
        $groups = ['foo', 'bar', 'baz'];
1132
1133
        $admin->setFormGroups($groups);
1134
        $this->assertSame($groups, $admin->getFormGroups());
1135
    }
1136
1137
    public function testGetMaxPageLinks(): void
1138
    {
1139
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1140
1141
        $this->assertSame(25, $admin->getMaxPageLinks());
1142
1143
        $admin->setMaxPageLinks(14);
1144
        $this->assertSame(14, $admin->getMaxPageLinks());
1145
    }
1146
1147
    public function testGetMaxPerPage(): void
1148
    {
1149
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1150
1151
        $this->assertSame(32, $admin->getMaxPerPage());
1152
1153
        $admin->setMaxPerPage(94);
1154
        $this->assertSame(94, $admin->getMaxPerPage());
1155
    }
1156
1157
    public function testGetLabel(): void
1158
    {
1159
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1160
1161
        $this->assertNull($admin->getLabel());
1162
1163
        $admin->setLabel('FooLabel');
1164
        $this->assertSame('FooLabel', $admin->getLabel());
1165
    }
1166
1167
    public function testGetBaseController(): void
1168
    {
1169
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1170
1171
        $this->assertSame('Sonata\NewsBundle\Controller\PostAdminController', $admin->getBaseControllerName());
1172
1173
        $admin->setBaseControllerName('Sonata\NewsBundle\Controller\FooAdminController');
1174
        $this->assertSame('Sonata\NewsBundle\Controller\FooAdminController', $admin->getBaseControllerName());
1175
    }
1176
1177
    public function testGetIdParameter(): void
1178
    {
1179
        $postAdmin = new PostAdmin(
1180
            'sonata.post.admin.post',
1181
            'NewsBundle\Entity\Post',
1182
            'Sonata\NewsBundle\Controller\PostAdminController'
1183
        );
1184
1185
        $this->assertSame('id', $postAdmin->getIdParameter());
1186
        $this->assertFalse($postAdmin->isChild());
1187
1188
        $commentAdmin = new CommentAdmin(
1189
            'sonata.post.admin.comment',
1190
            'Application\Sonata\NewsBundle\Entity\Comment',
1191
            'Sonata\NewsBundle\Controller\CommentAdminController'
1192
        );
1193
        $commentAdmin->setParent($postAdmin);
1194
1195
        $this->assertTrue($commentAdmin->isChild());
1196
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1197
1198
        $commentVoteAdmin = new CommentVoteAdmin(
1199
            'sonata.post.admin.comment_vote',
1200
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1201
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
1202
        );
1203
        $commentVoteAdmin->setParent($commentAdmin);
1204
1205
        $this->assertTrue($commentVoteAdmin->isChild());
1206
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1207
    }
1208
1209
    public function testGetExportFormats(): void
1210
    {
1211
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1212
1213
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1214
    }
1215
1216
    public function testGetUrlsafeIdentifier(): void
1217
    {
1218
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1219
1220
        $entity = new \stdClass();
1221
1222
        $modelManager = $this->createMock(ModelManagerInterface::class);
1223
        $modelManager->expects($this->once())
1224
            ->method('getUrlSafeIdentifier')
1225
            ->with($this->equalTo($entity))
1226
            ->willReturn('foo');
1227
        $admin->setModelManager($modelManager);
1228
1229
        $this->assertSame('foo', $admin->getUrlSafeIdentifier($entity));
1230
    }
1231
1232
    public function testDeterminedPerPageValue(): void
1233
    {
1234
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1235
1236
        $this->assertFalse($admin->determinedPerPageValue('foo'));
1237
        $this->assertFalse($admin->determinedPerPageValue(123));
1238
        $this->assertTrue($admin->determinedPerPageValue(16));
1239
1240
        $admin->setPerPageOptions([101, 102, 103]);
1241
        $this->assertFalse($admin->determinedPerPageValue(16));
1242
        $this->assertTrue($admin->determinedPerPageValue(101));
1243
    }
1244
1245
    public function testIsGranted(): void
1246
    {
1247
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1248
        $modelManager = $this->createStub(ModelManagerInterface::class);
1249
        $modelManager
1250
            ->method('getNormalizedIdentifier')
1251
            ->willReturnCallback(static function (?object $entity = null): ?string {
1252
                return $entity ? $entity->id : null;
1253
            });
1254
1255
        $admin->setModelManager($modelManager);
1256
1257
        $entity1 = new \stdClass();
1258
        $entity1->id = '1';
1259
1260
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1261
        $securityHandler
1262
            ->expects($this->exactly(6))
1263
            ->method('isGranted')
1264
            ->willReturnCallback(static function (
1265
                AdminInterface $adminIn,
1266
                string $attributes,
1267
                ?object $object = null
1268
            ) use (
1269
                $admin,
1270
                $entity1
1271
            ): bool {
1272
                return $admin === $adminIn && 'FOO' === $attributes &&
1273
                    ($object === $admin || $object === $entity1);
1274
            });
1275
1276
        $admin->setSecurityHandler($securityHandler);
1277
1278
        $this->assertTrue($admin->isGranted('FOO'));
1279
        $this->assertTrue($admin->isGranted('FOO'));
1280
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1281
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1282
        $this->assertFalse($admin->isGranted('BAR'));
1283
        $this->assertFalse($admin->isGranted('BAR'));
1284
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1285
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1286
1287
        $entity2 = new \stdClass();
1288
        $entity2->id = '2';
1289
1290
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1291
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1292
1293
        $entity3 = new \stdClass();
1294
        $entity3->id = '3';
1295
1296
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1297
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1298
    }
1299
1300
    public function testSupportsPreviewMode(): void
1301
    {
1302
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1303
1304
        $this->assertFalse($admin->supportsPreviewMode());
1305
    }
1306
1307
    public function testGetPermissionsShow(): void
1308
    {
1309
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1310
1311
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1312
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1313
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1314
    }
1315
1316
    public function testShowIn(): void
1317
    {
1318
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1319
1320
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1321
        $securityHandler
1322
            ->method('isGranted')
1323
            ->willReturnCallback(static function (AdminInterface $adminIn, array $attributes, $object = null) use ($admin): 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...
1324
                return $admin === $adminIn && $attributes === ['LIST'];
1325
            });
1326
1327
        $admin->setSecurityHandler($securityHandler);
1328
1329
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1330
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1331
        $this->assertTrue($admin->showIn('foo'));
1332
    }
1333
1334
    public function testGetObjectIdentifier(): void
1335
    {
1336
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1337
1338
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1339
    }
1340
1341
    /**
1342
     * @group legacy
1343
     */
1344
    public function testTrans(): void
1345
    {
1346
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1347
        $admin->setTranslationDomain('fooMessageDomain');
1348
1349
        $translator = $this->createMock(TranslatorInterface::class);
1350
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1351
1352
        $translator->expects($this->once())
1353
            ->method('trans')
1354
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1355
            ->willReturn('fooTranslated');
1356
1357
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1358
    }
1359
1360
    /**
1361
     * @group legacy
1362
     */
1363
    public function testTransWithMessageDomain(): void
1364
    {
1365
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1366
1367
        $translator = $this->createMock(TranslatorInterface::class);
1368
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1369
1370
        $translator->expects($this->once())
1371
            ->method('trans')
1372
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1373
            ->willReturn('fooTranslated');
1374
1375
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1376
    }
1377
1378
    /**
1379
     * @group legacy
1380
     */
1381
    public function testTransChoice(): void
1382
    {
1383
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1384
        $admin->setTranslationDomain('fooMessageDomain');
1385
1386
        $translator = $this->createMock(TranslatorInterface::class);
1387
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1388
1389
        $translator->expects($this->once())
1390
            ->method('transChoice')
1391
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1392
            ->willReturn('fooTranslated');
1393
1394
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::transChoice() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1395
    }
1396
1397
    /**
1398
     * @group legacy
1399
     */
1400
    public function testTransChoiceWithMessageDomain(): void
1401
    {
1402
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1403
1404
        $translator = $this->createMock(TranslatorInterface::class);
1405
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1406
1407
        $translator->expects($this->once())
1408
            ->method('transChoice')
1409
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1410
            ->willReturn('fooTranslated');
1411
1412
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2, ['name' => 'Andrej'], 'fooMessageDomain'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::transChoice() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1413
    }
1414
1415
    public function testSetFilterPersister(): void
1416
    {
1417
        $admin = new class('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController') extends PostAdmin {
1418
            public function persistFilters(): bool
1419
            {
1420
                return $this->persistFilters;
0 ignored issues
show
Deprecated Code introduced by
The property Sonata\AdminBundle\Admin...tAdmin::$persistFilters has been deprecated with message: since sonata-project/admin-bundle 3.34, to be removed in 4.0.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1421
            }
1422
        };
1423
1424
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1425
1426
        $admin->setFilterPersister($filterPersister);
1427
        $this->assertTrue($admin->persistFilters());
1428
    }
1429
1430
    public function testGetRootCode(): void
1431
    {
1432
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1433
1434
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1435
1436
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1437
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1438
        $parentFieldDescription->expects($this->once())
1439
            ->method('getAdmin')
1440
            ->willReturn($parentAdmin);
1441
1442
        $this->assertNull($admin->getParentFieldDescription());
1443
        $admin->setParentFieldDescription($parentFieldDescription);
1444
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1445
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1446
    }
1447
1448
    public function testGetRoot(): void
1449
    {
1450
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1451
1452
        $this->assertSame($admin, $admin->getRoot());
1453
1454
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1455
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1456
        $parentFieldDescription->expects($this->once())
1457
            ->method('getAdmin')
1458
            ->willReturn($parentAdmin);
1459
1460
        $this->assertNull($admin->getParentFieldDescription());
1461
        $admin->setParentFieldDescription($parentFieldDescription);
1462
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1463
        $this->assertSame($parentAdmin, $admin->getRoot());
1464
    }
1465
1466
    public function testGetExportFields(): void
1467
    {
1468
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1469
1470
        $modelManager = $this->createMock(ModelManagerInterface::class);
1471
        $modelManager->expects($this->once())
1472
            ->method('getExportFields')
1473
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1474
            ->willReturn(['foo', 'bar']);
1475
1476
        $admin->setModelManager($modelManager);
1477
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1478
    }
1479
1480
    public function testGetPersistentParametersWithNoExtension(): void
1481
    {
1482
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1483
1484
        $this->assertEmpty($admin->getPersistentParameters());
1485
    }
1486
1487
    public function testGetPersistentParametersWithInvalidExtension(): void
1488
    {
1489
        $this->expectException(\RuntimeException::class);
1490
1491
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1492
1493
        $extension = $this->createMock(AdminExtensionInterface::class);
1494
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn(null);
1495
1496
        $admin->addExtension($extension);
1497
1498
        $admin->getPersistentParameters();
1499
    }
1500
1501
    public function testGetPersistentParametersWithValidExtension(): void
1502
    {
1503
        $expected = [
1504
            'context' => 'foobar',
1505
        ];
1506
1507
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1508
1509
        $extension = $this->createMock(AdminExtensionInterface::class);
1510
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1511
1512
        $admin->addExtension($extension);
1513
1514
        $this->assertSame($expected, $admin->getPersistentParameters());
1515
    }
1516
1517
    public function testGetFormWithNonCollectionParentValue(): void
1518
    {
1519
        $post = new Post();
1520
        $tagAdmin = $this->createTagAdmin($post);
1521
        $tag = $tagAdmin->getSubject();
1522
1523
        $tag->setPosts(null);
1524
        $tagAdmin->getForm();
1525
        $this->assertSame($post, $tag->getPosts());
1526
    }
1527
1528
    public function testGetFormWithCollectionParentValue(): void
1529
    {
1530
        $post = new Post();
1531
        $tagAdmin = $this->createTagAdmin($post);
1532
        $tag = $tagAdmin->getSubject();
1533
1534
        // Case of a doctrine collection
1535
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1536
        $this->assertCount(0, $tag->getPosts());
1537
1538
        $tag->addPost(new Post());
1539
1540
        $this->assertCount(1, $tag->getPosts());
1541
1542
        $tagAdmin->getForm();
1543
1544
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1545
        $this->assertCount(2, $tag->getPosts());
1546
        $this->assertContains($post, $tag->getPosts());
1547
1548
        // Case of an array
1549
        $tag->setPosts([]);
1550
        $this->assertCount(0, $tag->getPosts());
1551
1552
        $tag->addPost(new Post());
1553
1554
        $this->assertCount(1, $tag->getPosts());
1555
1556
        $tagAdmin->getForm();
1557
1558
        $this->assertIsArray($tag->getPosts());
1559
        $this->assertCount(2, $tag->getPosts());
1560
        $this->assertContains($post, $tag->getPosts());
1561
    }
1562
1563
    public function testFormAddPostSubmitEventForPreValidation(): void
1564
    {
1565
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1566
        $object = new \stdClass();
1567
1568
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1569
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1570
1571
        $validator = $this->createMock(ValidatorInterface::class);
1572
        $validator
1573
                ->method('getMetadataFor')
1574
                ->willReturn($this->createMock(MemberMetadata::class));
1575
        $modelAdmin->setValidator($validator);
1576
1577
        $modelManager = $this->createMock(ModelManagerInterface::class);
1578
        $modelManager
1579
            ->method('getNewFieldDescriptionInstance')
1580
            ->willReturn(new FieldDescription());
1581
        $modelAdmin->setModelManager($modelManager);
1582
1583
        // a Admin class to test that preValidate is called
1584
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1585
        $testAdminPreValidate->expects($this->once())
1586
                ->method('preValidate')
1587
                ->with($this->identicalTo($object));
1588
1589
        $event = $this->createMock(FormEvent::class);
1590
        $event
1591
                ->method('getData')
1592
                ->willReturn($object);
1593
1594
        $formBuild = $this->createMock(FormBuilder::class);
1595
        $formBuild->expects($this->once())
1596
                ->method('addEventListener')
1597
                ->with(
1598
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1599
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1600
                        if (\is_callable($callback)) {
1601
                            $closure = $callback->bindTo($testAdminPreValidate);
0 ignored issues
show
Bug introduced by
The method bindTo cannot be called on $callback (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1602
                            $closure($event);
1603
1604
                            return true;
1605
                        }
1606
1607
                        return false;
1608
                    }),
1609
                    $this->greaterThan(0)
1610
                );
1611
1612
        $formContractor = $this->createMock(FormContractorInterface::class);
1613
        $formContractor
1614
                ->method('getDefaultOptions')
1615
                ->willReturn([]);
1616
        $formContractor
1617
                ->method('getFormBuilder')
1618
                ->willReturn($formBuild);
1619
1620
        $modelAdmin->setFormContractor($formContractor);
1621
        $modelAdmin->setSubject($object);
1622
        $modelAdmin->defineFormBuilder($formBuild);
1623
        $modelAdmin->getForm();
1624
    }
1625
1626
    public function testRemoveFieldFromFormGroup(): void
1627
    {
1628
        $formGroups = [
1629
            'foobar' => [
1630
                'fields' => [
1631
                    'foo' => 'foo',
1632
                    'bar' => 'bar',
1633
                ],
1634
            ],
1635
        ];
1636
1637
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1638
        $admin->setFormGroups($formGroups);
1639
1640
        $admin->removeFieldFromFormGroup('foo');
1641
        $this->assertSame($admin->getFormGroups(), [
1642
            'foobar' => [
1643
                'fields' => [
1644
                    'bar' => 'bar',
1645
                ],
1646
            ],
1647
        ]);
1648
1649
        $admin->removeFieldFromFormGroup('bar');
1650
        $this->assertSame($admin->getFormGroups(), []);
1651
    }
1652
1653
    public function testGetFilterParameters(): void
1654
    {
1655
        $authorId = uniqid();
1656
1657
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1658
1659
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1660
        $commentAdmin->setParentAssociationMapping('post.author');
1661
        $commentAdmin->setParent($postAdmin);
1662
1663
        $request = $this->createMock(Request::class);
1664
        $query = $this->createMock(ParameterBag::class);
1665
        $query
1666
            ->method('get')
1667
            ->willReturn([
1668
                'filter' => [
1669
                    '_page' => '1',
1670
                    '_per_page' => '32',
1671
                ],
1672
            ]);
1673
1674
        $request->query = $query;
1675
        $request
1676
            ->method('get')
1677
            ->willReturn($authorId);
1678
1679
        $commentAdmin->setRequest($request);
1680
1681
        $modelManager = $this->createMock(ModelManagerInterface::class);
1682
        $modelManager
1683
            ->method('getDefaultSortValues')
1684
            ->willReturn([]);
1685
1686
        $commentAdmin->setModelManager($modelManager);
1687
1688
        $parameters = $commentAdmin->getFilterParameters();
1689
1690
        $this->assertTrue(isset($parameters['post__author']));
1691
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1692
    }
1693
1694
    public function testGetFilterFieldDescription(): void
1695
    {
1696
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1697
1698
        $fooFieldDescription = new FieldDescription();
1699
        $barFieldDescription = new FieldDescription();
1700
        $bazFieldDescription = new FieldDescription();
1701
1702
        $modelManager = $this->createMock(ModelManagerInterface::class);
1703
        $modelManager->expects($this->exactly(3))
1704
            ->method('getNewFieldDescriptionInstance')
1705
            ->willReturnCallback(static function ($adminClass, string $name, $filterOptions) use ($fooFieldDescription, $barFieldDescription, $bazFieldDescription) {
0 ignored issues
show
Unused Code introduced by
The parameter $filterOptions 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...
1706
                switch ($name) {
1707
                    case 'foo':
1708
                        $fieldDescription = $fooFieldDescription;
1709
1710
                        break;
1711
1712
                    case 'bar':
1713
                        $fieldDescription = $barFieldDescription;
1714
1715
                        break;
1716
1717
                    case 'baz':
1718
                        $fieldDescription = $bazFieldDescription;
1719
1720
                        break;
1721
1722
                    default:
1723
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1724
                        break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1725
                }
1726
1727
                $fieldDescription->setName($name);
1728
1729
                return $fieldDescription;
1730
            });
1731
1732
        $modelAdmin->setModelManager($modelManager);
1733
1734
        $pager = $this->createMock(PagerInterface::class);
1735
1736
        $datagrid = $this->createMock(DatagridInterface::class);
1737
        $datagrid->expects($this->once())
1738
            ->method('getPager')
1739
            ->willReturn($pager);
1740
1741
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1742
        $datagridBuilder->expects($this->once())
1743
            ->method('getBaseDatagrid')
1744
            ->with($this->identicalTo($modelAdmin), [])
1745
            ->willReturn($datagrid);
1746
1747
        $datagridBuilder->expects($this->exactly(3))
1748
            ->method('addFilter')
1749
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1750
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1751
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1752
            });
1753
1754
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1755
1756
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1757
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1758
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1759
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1760
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1761
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1762
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1763
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1764
    }
1765
1766
    public function testGetSubjectNoRequest(): void
1767
    {
1768
        $modelManager = $this->createMock(ModelManagerInterface::class);
1769
        $modelManager
1770
            ->expects($this->never())
1771
            ->method('find');
1772
1773
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1774
        $admin->setModelManager($modelManager);
1775
1776
        $this->assertNull($admin->getSubject());
1777
    }
1778
1779
    public function testGetSideMenu(): void
1780
    {
1781
        $item = $this->createMock(ItemInterface::class);
1782
        $item
1783
            ->expects($this->once())
1784
            ->method('setChildrenAttribute')
1785
            ->with('class', 'nav navbar-nav');
1786
        $item
1787
            ->expects($this->once())
1788
            ->method('setExtra')
1789
            ->with('translation_domain', 'foo_bar_baz');
1790
1791
        $menuFactory = $this->createMock(FactoryInterface::class);
1792
        $menuFactory
1793
            ->expects($this->once())
1794
            ->method('createItem')
1795
            ->willReturn($item);
1796
1797
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1798
        $modelAdmin->setMenuFactory($menuFactory);
1799
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1800
1801
        $modelAdmin->getSideMenu('foo');
1802
    }
1803
1804
    /**
1805
     * @return array
1806
     */
1807
    public function provideGetSubject()
1808
    {
1809
        return [
1810
            [23],
1811
            ['azerty'],
1812
            ['4f69bbb5f14a13347f000092'],
1813
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1814
            ['123'.AdapterInterface::ID_SEPARATOR.'my_type'], // composite keys are supported
1815
        ];
1816
    }
1817
1818
    /**
1819
     * @dataProvider provideGetSubject
1820
     */
1821
    public function testGetSubjectFailed($id): void
1822
    {
1823
        $modelManager = $this->createMock(ModelManagerInterface::class);
1824
        $modelManager
1825
            ->expects($this->once())
1826
            ->method('find')
1827
            ->with('NewsBundle\Entity\Post', $id)
1828
            ->willReturn(null); // entity not found
1829
1830
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1831
        $admin->setModelManager($modelManager);
1832
1833
        $admin->setRequest(new Request(['id' => $id]));
1834
        $this->assertNull($admin->getSubject());
1835
    }
1836
1837
    /**
1838
     * @dataProvider provideGetSubject
1839
     */
1840
    public function testGetSubject($id): void
1841
    {
1842
        $entity = new Post();
1843
1844
        $modelManager = $this->createMock(ModelManagerInterface::class);
1845
        $modelManager
1846
            ->expects($this->once())
1847
            ->method('find')
1848
            ->with('NewsBundle\Entity\Post', $id)
1849
            ->willReturn($entity);
1850
1851
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1852
        $admin->setModelManager($modelManager);
1853
1854
        $admin->setRequest(new Request(['id' => $id]));
1855
        $this->assertSame($entity, $admin->getSubject());
1856
        $this->assertSame($entity, $admin->getSubject()); // model manager must be used only once
1857
    }
1858
1859
    public function testGetSubjectWithParentDescription(): void
1860
    {
1861
        $adminId = 1;
1862
1863
        $comment = new Comment();
1864
1865
        $modelManager = $this->createMock(ModelManagerInterface::class);
1866
        $modelManager
1867
            ->method('find')
1868
            ->with('NewsBundle\Entity\Comment', $adminId)
1869
            ->willReturn($comment);
1870
1871
        $request = new Request(['id' => $adminId]);
1872
1873
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1874
        $postAdmin->setRequest($request);
1875
1876
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1877
        $commentAdmin->setRequest($request);
1878
        $commentAdmin->setModelManager($modelManager);
1879
1880
        $this->assertSame($comment, $commentAdmin->getSubject());
1881
1882
        $commentAdmin->setSubject(null);
1883
        $commentAdmin->setParentFieldDescription(new FieldDescription());
1884
1885
        $this->assertNull($commentAdmin->getSubject());
1886
    }
1887
1888
    /**
1889
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1890
     */
1891
    public function testGetActionButtonsList(): void
1892
    {
1893
        $expected = [
1894
            'create' => [
1895
                'template' => 'Foo.html.twig',
1896
            ],
1897
        ];
1898
1899
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1900
1901
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1902
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
1903
1904
        $admin->setTemplateRegistry($templateRegistry->reveal());
1905
1906
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1907
        $securityHandler
1908
            ->expects($this->once())
1909
            ->method('isGranted')
1910
            ->with($admin, 'CREATE', $admin)
1911
            ->willReturn(true);
1912
        $admin->setSecurityHandler($securityHandler);
1913
1914
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1915
        $routeGenerator
1916
            ->expects($this->once())
1917
            ->method('hasAdminRoute')
1918
            ->with($admin, 'create')
1919
            ->willReturn(true);
1920
        $admin->setRouteGenerator($routeGenerator);
1921
1922
        $this->assertSame($expected, $admin->getActionButtons('list', null));
1923
    }
1924
1925
    /**
1926
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1927
     */
1928
    public function testGetActionButtonsListCreateDisabled(): void
1929
    {
1930
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1931
1932
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1933
        $securityHandler
1934
            ->expects($this->once())
1935
            ->method('isGranted')
1936
            ->with($admin, 'CREATE', $admin)
1937
            ->willReturn(false);
1938
        $admin->setSecurityHandler($securityHandler);
1939
1940
        $this->assertSame([], $admin->getActionButtons('list', null));
1941
    }
1942
1943
    /**
1944
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
1945
     */
1946
    public function testGetBatchActions(): void
1947
    {
1948
        $expected = [
1949
            'delete' => [
1950
                'label' => 'action_delete',
1951
                'translation_domain' => 'SonataAdminBundle',
1952
                'ask_confirmation' => true, // by default always true
1953
            ],
1954
            'foo' => [
1955
                'label' => 'action_foo',
1956
                'translation_domain' => 'SonataAdminBundle',
1957
            ],
1958
            'bar' => [
1959
                'label' => 'batch.label_bar',
1960
                'translation_domain' => 'SonataAdminBundle',
1961
            ],
1962
            'baz' => [
1963
                'label' => 'action_baz',
1964
                'translation_domain' => 'AcmeAdminBundle',
1965
            ],
1966
        ];
1967
1968
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
1969
1970
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1971
        $labelTranslatorStrategy
1972
            ->method('getLabel')
1973
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
1974
                return $context.'.'.$type.'_'.$label;
1975
            });
1976
1977
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1978
        $admin->setRouteBuilder($pathInfo);
1979
        $admin->setTranslationDomain('SonataAdminBundle');
1980
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1981
1982
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1983
        $routeGenerator
1984
            ->expects($this->once())
1985
            ->method('hasAdminRoute')
1986
            ->with($admin, 'delete')
1987
            ->willReturn(true);
1988
        $admin->setRouteGenerator($routeGenerator);
1989
1990
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1991
        $securityHandler
1992
            ->method('isGranted')
1993
            ->willReturnCallback(static function (AdminInterface $adminIn, string $attributes, $object = null) use ($admin): 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...
1994
                return $admin === $adminIn && 'DELETE' === $attributes;
1995
            });
1996
        $admin->setSecurityHandler($securityHandler);
1997
1998
        $this->assertSame($expected, $admin->getBatchActions());
1999
    }
2000
2001
    /**
2002
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2003
     */
2004
    public function testShowMosaicButton(): void
2005
    {
2006
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2007
        $listModes = $admin->getListModes();
2008
2009
        $admin->showMosaicButton(true);
2010
2011
        $this->assertSame($listModes, $admin->getListModes());
2012
    }
2013
2014
    /**
2015
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2016
     */
2017
    public function testShowMosaicButtonHideMosaic(): void
2018
    {
2019
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2020
        $listModes = $admin->getListModes();
2021
        $expected['list'] = $listModes['list'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$expected was never initialized. Although not strictly required by PHP, it is generally a good practice to add $expected = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2022
2023
        $admin->showMosaicButton(false);
2024
2025
        $this->assertSame($expected, $admin->getListModes());
2026
    }
2027
2028
    /**
2029
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2030
     * @dataProvider provideGetBaseRouteName
2031
     */
2032
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2033
    {
2034
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2035
2036
        $routeGenerator = new DefaultRouteGenerator(
2037
            $this->createMock(RouterInterface::class),
2038
            new RoutesCache($this->cacheTempFolder, true)
2039
        );
2040
2041
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
2042
        $admin->setRouteBuilder($pathInfo);
2043
        $admin->setRouteGenerator($routeGenerator);
2044
        $admin->initialize();
2045
2046
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2047
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2048
2049
        $admin->setTemplateRegistry($templateRegistry->reveal());
2050
2051
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2052
        $securityHandler
2053
            ->method('isGranted')
2054
            ->willReturnCallback(static function (AdminInterface $adminIn, string $attributes, $object = null) use ($admin): 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...
2055
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2056
            });
2057
2058
        $admin->setSecurityHandler($securityHandler);
2059
2060
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2061
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2062
    }
2063
2064
    public function testDefaultFilters(): void
2065
    {
2066
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2067
2068
        $subjectId = uniqid();
2069
2070
        $request = $this->createMock(Request::class);
2071
        $query = $this->createMock(ParameterBag::class);
2072
        $query
2073
            ->method('get')
2074
            ->with($this->equalTo('filter'))
2075
            ->willReturn([
2076
                'a' => [
2077
                    'value' => 'b',
2078
                ],
2079
                'foo' => [
2080
                    'type' => '1',
2081
                    'value' => 'bar',
2082
                ],
2083
                'baz' => [
2084
                    'type' => '5',
2085
                    'value' => 'test',
2086
                ],
2087
            ]);
2088
        $request->query = $query;
2089
2090
        $request
2091
            ->method('get')
2092
            ->willReturn($subjectId);
2093
2094
        $admin->setRequest($request);
2095
2096
        $modelManager = $this->createMock(ModelManagerInterface::class);
2097
        $modelManager
2098
            ->method('getDefaultSortValues')
2099
            ->willReturn([]);
2100
2101
        $admin->setModelManager($modelManager);
2102
2103
        $this->assertSame([
2104
            '_page' => 1,
2105
            '_per_page' => 32,
2106
            'foo' => [
2107
                'type' => '1',
2108
                'value' => 'bar',
2109
            ],
2110
            'baz' => [
2111
                'type' => '5',
2112
                'value' => 'test',
2113
            ],
2114
            'a' => [
2115
                'value' => 'b',
2116
            ],
2117
        ], $admin->getFilterParameters());
2118
2119
        $this->assertTrue($admin->isDefaultFilter('foo'));
2120
        $this->assertFalse($admin->isDefaultFilter('bar'));
2121
        $this->assertFalse($admin->isDefaultFilter('a'));
2122
    }
2123
2124
    /**
2125
     * NEXT_MAJOR: remove this method.
2126
     *
2127
     * @group legacy
2128
     */
2129
    public function testCreateQueryLegacyCallWorks(): void
2130
    {
2131
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2132
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2133
        ]);
2134
        $query = $this->createMock(ProxyQueryInterface::class);
2135
        $modelManager = $this->createMock(ModelManagerInterface::class);
2136
        $modelManager->expects($this->once())
2137
            ->method('createQuery')
2138
            ->with('My\Class')
2139
            ->willReturn($query);
2140
2141
        $admin->setModelManager($modelManager);
2142
        $this->assertSame($query, $admin->createQuery('list'));
2143
    }
2144
2145
    public function testGetDataSourceIterator(): void
2146
    {
2147
        $datagrid = $this->createMock(DatagridInterface::class);
2148
        $datagrid->method('buildPager');
2149
2150
        $modelManager = $this->createMock(ModelManagerInterface::class);
2151
        $modelManager->method('getExportFields')->willReturn([
2152
            'field',
2153
            'foo',
2154
            'bar',
2155
        ]);
2156
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2157
            ->with($this->equalTo($datagrid), $this->equalTo([
2158
                'Feld' => 'field',
2159
                1 => 'foo',
2160
                2 => 'bar',
2161
            ]));
2162
2163
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2164
            ->disableOriginalConstructor()
2165
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2166
            ->getMockForAbstractClass();
2167
        $admin->method('getDatagrid')->willReturn($datagrid);
2168
        $admin->setModelManager($modelManager);
2169
2170
        $admin
2171
            ->method('getTranslationLabel')
2172
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2173
                return $context.'.'.$type.'_'.$label;
2174
            });
2175
        $admin
2176
            ->method('trans')
2177
            ->willReturnCallback(static function (string $label): string {
2178
                if ('export.label_field' === $label) {
2179
                    return 'Feld';
2180
                }
2181
2182
                return $label;
2183
            });
2184
2185
        $admin->getDataSourceIterator();
2186
    }
2187
2188
    public function testCircularChildAdmin(): void
2189
    {
2190
        $this->expectException(\RuntimeException::class);
2191
        $this->expectExceptionMessage(
2192
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2193
        );
2194
2195
        $postAdmin = new PostAdmin(
2196
            'sonata.post.admin.post',
2197
            'Application\Sonata\NewsBundle\Entity\Post',
2198
            'Sonata\NewsBundle\Controller\PostAdminController'
2199
        );
2200
        $commentAdmin = new CommentAdmin(
2201
            'sonata.post.admin.comment',
2202
            'Application\Sonata\NewsBundle\Entity\Comment',
2203
            'Sonata\NewsBundle\Controller\CommentAdminController'
2204
        );
2205
        $postAdmin->addChild($commentAdmin, 'post');
2206
        $commentAdmin->addChild($postAdmin, 'comment');
2207
    }
2208
2209
    public function testCircularChildAdminTripleLevel(): void
2210
    {
2211
        $this->expectException(\RuntimeException::class);
2212
        $this->expectExceptionMessage(
2213
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2214
        );
2215
2216
        $postAdmin = new PostAdmin(
2217
            'sonata.post.admin.post',
2218
            'Application\Sonata\NewsBundle\Entity\Post',
2219
            'Sonata\NewsBundle\Controller\PostAdminController'
2220
        );
2221
        $commentAdmin = new CommentAdmin(
2222
            'sonata.post.admin.comment',
2223
            'Application\Sonata\NewsBundle\Entity\Comment',
2224
            'Sonata\NewsBundle\Controller\CommentAdminController'
2225
        );
2226
        $commentVoteAdmin = new CommentVoteAdmin(
2227
            'sonata.post.admin.comment_vote',
2228
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2229
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2230
        );
2231
        $postAdmin->addChild($commentAdmin, 'post');
2232
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2233
        $commentVoteAdmin->addChild($postAdmin, 'post');
2234
    }
2235
2236
    public function testCircularChildAdminWithItself(): void
2237
    {
2238
        $this->expectException(\RuntimeException::class);
2239
        $this->expectExceptionMessage(
2240
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2241
        );
2242
2243
        $postAdmin = new PostAdmin(
2244
            'sonata.post.admin.post',
2245
            'Application\Sonata\NewsBundle\Entity\Post',
2246
            'Sonata\NewsBundle\Controller\PostAdminController'
2247
        );
2248
        $postAdmin->addChild($postAdmin);
2249
    }
2250
2251
    public function testGetRootAncestor(): void
2252
    {
2253
        $postAdmin = new PostAdmin(
2254
            'sonata.post.admin.post',
2255
            'Application\Sonata\NewsBundle\Entity\Post',
2256
            'Sonata\NewsBundle\Controller\PostAdminController'
2257
        );
2258
        $commentAdmin = new CommentAdmin(
2259
            'sonata.post.admin.comment',
2260
            'Application\Sonata\NewsBundle\Entity\Comment',
2261
            'Sonata\NewsBundle\Controller\CommentAdminController'
2262
        );
2263
        $commentVoteAdmin = new CommentVoteAdmin(
2264
            'sonata.post.admin.comment_vote',
2265
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2266
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2267
        );
2268
2269
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2270
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2271
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2272
2273
        $postAdmin->addChild($commentAdmin, 'post');
2274
2275
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2276
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2277
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2278
2279
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2280
2281
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2282
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2283
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2284
    }
2285
2286
    public function testGetChildDepth(): void
2287
    {
2288
        $postAdmin = new PostAdmin(
2289
            'sonata.post.admin.post',
2290
            'Application\Sonata\NewsBundle\Entity\Post',
2291
            'Sonata\NewsBundle\Controller\PostAdminController'
2292
        );
2293
        $commentAdmin = new CommentAdmin(
2294
            'sonata.post.admin.comment',
2295
            'Application\Sonata\NewsBundle\Entity\Comment',
2296
            'Sonata\NewsBundle\Controller\CommentAdminController'
2297
        );
2298
        $commentVoteAdmin = new CommentVoteAdmin(
2299
            'sonata.post.admin.comment_vote',
2300
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2301
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2302
        );
2303
2304
        $this->assertSame(0, $postAdmin->getChildDepth());
2305
        $this->assertSame(0, $commentAdmin->getChildDepth());
2306
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2307
2308
        $postAdmin->addChild($commentAdmin, 'post');
2309
2310
        $this->assertSame(0, $postAdmin->getChildDepth());
2311
        $this->assertSame(1, $commentAdmin->getChildDepth());
2312
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2313
2314
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2315
2316
        $this->assertSame(0, $postAdmin->getChildDepth());
2317
        $this->assertSame(1, $commentAdmin->getChildDepth());
2318
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2319
    }
2320
2321
    public function testGetCurrentLeafChildAdmin(): void
2322
    {
2323
        $postAdmin = new PostAdmin(
2324
            'sonata.post.admin.post',
2325
            'Application\Sonata\NewsBundle\Entity\Post',
2326
            'Sonata\NewsBundle\Controller\PostAdminController'
2327
        );
2328
        $commentAdmin = new CommentAdmin(
2329
            'sonata.post.admin.comment',
2330
            'Application\Sonata\NewsBundle\Entity\Comment',
2331
            'Sonata\NewsBundle\Controller\CommentAdminController'
2332
        );
2333
        $commentVoteAdmin = new CommentVoteAdmin(
2334
            'sonata.post.admin.comment_vote',
2335
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2336
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2337
        );
2338
2339
        $postAdmin->addChild($commentAdmin, 'post');
2340
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2341
2342
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2343
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2344
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2345
2346
        $commentAdmin->setCurrentChild(true);
2347
2348
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2349
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2350
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2351
2352
        $commentVoteAdmin->setCurrentChild(true);
2353
2354
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2355
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2356
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2357
    }
2358
2359
    public function testAdminWithoutControllerName(): void
2360
    {
2361
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', null);
2362
2363
        $this->assertNull($admin->getBaseControllerName());
2364
    }
2365
2366
    /**
2367
     * NEXT_MAJOR: Remove this test and its data provider.
2368
     *
2369
     * @group legacy
2370
     *
2371
     * @dataProvider getDeprecatedAbstractAdminConstructorArgs
2372
     *
2373
     * @expectedDeprecation Passing other type than string%S as argument %d for method Sonata\AdminBundle\Admin\AbstractAdmin::__construct() is deprecated since sonata-project/admin-bundle 3.65. It will accept only string%S in version 4.0.
2374
     */
2375
    public function testDeprecatedAbstractAdminConstructorArgs($code, $class, $baseControllerName): void
2376
    {
2377
        new PostAdmin($code, $class, $baseControllerName);
2378
    }
2379
2380
    public function getDeprecatedAbstractAdminConstructorArgs(): iterable
2381
    {
2382
        yield from [
2383
            ['sonata.post.admin.post', null, null],
2384
            [null, null, null],
2385
            ['sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', false],
2386
            ['sonata.post.admin.post', false, false],
2387
            [false, false, false],
2388
            [true, true, true],
2389
            [new \stdClass(), new \stdClass(), new \stdClass()],
2390
            [0, 0, 0],
2391
            [1, 1, 1],
2392
        ];
2393
    }
2394
2395
    private function createTagAdmin(Post $post): TagAdmin
2396
    {
2397
        $postAdmin = $this->getMockBuilder(PostAdmin::class)
2398
            ->disableOriginalConstructor()
2399
            ->getMock();
2400
2401
        $postAdmin->method('getObject')->willReturn($post);
2402
2403
        $formBuilder = $this->createMock(FormBuilderInterface::class);
2404
        $formBuilder->method('getForm')->willReturn(null);
2405
2406
        $tagAdmin = $this->getMockBuilder(TagAdmin::class)
2407
            ->setConstructorArgs([
2408
                'admin.tag',
2409
                Tag::class,
2410
                'MyBundle\MyController',
2411
            ])
2412
            ->setMethods(['getFormBuilder'])
2413
            ->getMock();
2414
2415
        $tagAdmin->method('getFormBuilder')->willReturn($formBuilder);
2416
        $tagAdmin->setParent($postAdmin);
2417
2418
        $tag = new Tag();
2419
        $tagAdmin->setSubject($tag);
2420
2421
        $request = $this->createMock(Request::class);
2422
        $tagAdmin->setRequest($request);
2423
2424
        $configurationPool = $this->getMockBuilder(Pool::class)
2425
            ->disableOriginalConstructor()
2426
            ->getMock();
2427
2428
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
2429
2430
        $tagAdmin->setConfigurationPool($configurationPool);
2431
2432
        return $tagAdmin;
2433
    }
2434
}
2435