Completed
Pull Request — 3.x (#6171)
by Vincent
02:58
created

AdminTest::testHasAccessOnMadeUpAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Tests\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\BreadcrumbsBuilder;
25
use Sonata\AdminBundle\Admin\BreadcrumbsBuilderInterface;
26
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
27
use Sonata\AdminBundle\Admin\Pool;
28
use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
29
use Sonata\AdminBundle\Builder\FormContractorInterface;
30
use Sonata\AdminBundle\Builder\ListBuilderInterface;
31
use Sonata\AdminBundle\Builder\RouteBuilderInterface;
32
use Sonata\AdminBundle\Builder\ShowBuilderInterface;
33
use Sonata\AdminBundle\Datagrid\DatagridInterface;
34
use Sonata\AdminBundle\Datagrid\PagerInterface;
35
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
36
use Sonata\AdminBundle\Filter\Persister\FilterPersisterInterface;
37
use Sonata\AdminBundle\Model\AuditManagerInterface;
38
use Sonata\AdminBundle\Model\ModelManagerInterface;
39
use Sonata\AdminBundle\Route\DefaultRouteGenerator;
40
use Sonata\AdminBundle\Route\PathInfoBuilder;
41
use Sonata\AdminBundle\Route\RouteGeneratorInterface;
42
use Sonata\AdminBundle\Route\RoutesCache;
43
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
44
use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface;
45
use Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface;
46
use Sonata\AdminBundle\Tests\App\Builder\DatagridBuilder;
47
use Sonata\AdminBundle\Tests\App\Builder\FormContractor;
48
use Sonata\AdminBundle\Tests\App\Builder\ListBuilder;
49
use Sonata\AdminBundle\Tests\App\Builder\ShowBuilder;
50
use Sonata\AdminBundle\Tests\Fixtures\Admin\AvoidInfiniteLoopAdmin;
51
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentAdmin;
52
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentVoteAdmin;
53
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentWithCustomRouteAdmin;
54
use Sonata\AdminBundle\Tests\Fixtures\Admin\FieldDescription;
55
use Sonata\AdminBundle\Tests\Fixtures\Admin\FilteredAdmin;
56
use Sonata\AdminBundle\Tests\Fixtures\Admin\ModelAdmin;
57
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin;
58
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostWithCustomRouteAdmin;
59
use Sonata\AdminBundle\Tests\Fixtures\Admin\TagAdmin;
60
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\BlogPost;
61
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment;
62
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Post;
63
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\PostWithSingleTag;
64
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Tag;
65
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
66
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToStringNull;
67
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
68
use Sonata\Doctrine\Adapter\AdapterInterface;
69
use Symfony\Component\DependencyInjection\Container;
70
use Symfony\Component\DependencyInjection\ContainerInterface;
71
use Symfony\Component\Filesystem\Filesystem;
72
use Symfony\Component\Form\FormBuilder;
73
use Symfony\Component\Form\FormBuilderInterface;
74
use Symfony\Component\Form\FormEvent;
75
use Symfony\Component\Form\FormEvents;
76
use Symfony\Component\Form\FormFactory;
77
use Symfony\Component\Form\FormRegistry;
78
use Symfony\Component\Form\ResolvedFormTypeFactory;
79
use Symfony\Component\HttpFoundation\ParameterBag;
80
use Symfony\Component\HttpFoundation\Request;
81
use Symfony\Component\PropertyAccess\PropertyAccess;
82
use Symfony\Component\Routing\RouterInterface;
83
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
84
use Symfony\Component\Translation\TranslatorInterface;
85
use Symfony\Component\Validator\Mapping\MemberMetadata;
86
use Symfony\Component\Validator\Validator\ValidatorInterface;
87
88
class AdminTest extends TestCase
89
{
90
    protected $cacheTempFolder;
91
92
    protected function setUp(): void
93
    {
94
        $this->cacheTempFolder = sys_get_temp_dir().'/sonata_test_route';
95
        $filesystem = new Filesystem();
96
        $filesystem->remove($this->cacheTempFolder);
97
    }
98
99
    /**
100
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::__construct
101
     */
102
    public function testConstructor(): void
103
    {
104
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
105
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
106
107
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
108
        $this->assertInstanceOf(AbstractAdmin::class, $admin);
109
        $this->assertSame($class, $admin->getClass());
110
        $this->assertSame($baseControllerName, $admin->getBaseControllerName());
111
    }
112
113
    public function testGetClass(): void
114
    {
115
        $class = Post::class;
116
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
117
118
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
119
120
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
121
122
        $admin->setSubject(new BlogPost());
123
        $this->assertSame(BlogPost::class, $admin->getClass());
124
125
        $admin->setSubClasses(['foo']);
126
        $this->assertSame(BlogPost::class, $admin->getClass());
127
128
        $admin->setSubject(null);
129
        $admin->setSubClasses([]);
130
        $this->assertSame($class, $admin->getClass());
131
132
        $admin->setSubClasses(['foo' => 'bar']);
133
        $admin->setRequest(new Request(['subclass' => 'foo']));
134
        $this->assertSame('bar', $admin->getClass());
135
    }
136
137
    public function testGetClassException(): void
138
    {
139
        $this->expectException(\RuntimeException::class);
140
        $this->expectExceptionMessage('Feature not implemented: an embedded admin cannot have subclass');
141
142
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
143
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
144
145
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
146
        $admin->setParentFieldDescription(new FieldDescription());
147
        $admin->setSubClasses(['foo' => 'bar']);
148
        $admin->setRequest(new Request(['subclass' => 'foo']));
149
        $admin->getClass();
150
    }
151
152
    public function testCheckAccessThrowsExceptionOnMadeUpAction(): void
153
    {
154
        $admin = new PostAdmin(
155
            'sonata.post.admin.post',
156
            'Application\Sonata\NewsBundle\Entity\Post',
157
            'Sonata\NewsBundle\Controller\PostAdminController'
158
        );
159
        $this->expectException(
160
            \InvalidArgumentException::class
161
        );
162
        $this->expectExceptionMessage(
163
            'Action "made-up" could not be found'
164
        );
165
        $admin->checkAccess('made-up');
166
    }
167
168
    public function testCheckAccessThrowsAccessDeniedException(): void
169
    {
170
        $admin = new PostAdmin(
171
            'sonata.post.admin.post',
172
            'Application\Sonata\NewsBundle\Entity\Post',
173
            'Sonata\NewsBundle\Controller\PostAdminController'
174
        );
175
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
176
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
177
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
178
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
179
        $customExtension->getAccessMapping($admin)->willReturn(
180
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
181
        );
182
        $admin->addExtension($customExtension->reveal());
183
        $admin->setSecurityHandler($securityHandler->reveal());
184
        $this->expectException(
185
            AccessDeniedException::class
186
        );
187
        $this->expectExceptionMessage(
188
            'Access Denied to the action custom_action and role EXTRA_CUSTOM_ROLE'
189
        );
190
        $admin->checkAccess('custom_action');
191
    }
192
193
    public function testHasAccessOnMadeUpAction(): void
194
    {
195
        $admin = new PostAdmin(
196
            'sonata.post.admin.post',
197
            'Application\Sonata\NewsBundle\Entity\Post',
198
            'Sonata\NewsBundle\Controller\PostAdminController'
199
        );
200
201
        $this->assertFalse($admin->hasAccess('made-up'));
202
    }
203
204
    public function testHasAccess(): void
205
    {
206
        $admin = new PostAdmin(
207
            'sonata.post.admin.post',
208
            'Application\Sonata\NewsBundle\Entity\Post',
209
            'Sonata\NewsBundle\Controller\PostAdminController'
210
        );
211
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
212
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
213
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
214
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
215
        $customExtension->getAccessMapping($admin)->willReturn(
216
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
217
        );
218
        $admin->addExtension($customExtension->reveal());
219
        $admin->setSecurityHandler($securityHandler->reveal());
220
221
        $this->assertFalse($admin->hasAccess('custom_action'));
222
    }
223
224
    public function testHasAccessAllowsAccess(): void
225
    {
226
        $admin = new PostAdmin(
227
            'sonata.post.admin.post',
228
            'Application\Sonata\NewsBundle\Entity\Post',
229
            'Sonata\NewsBundle\Controller\PostAdminController'
230
        );
231
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
232
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
233
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(true);
234
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
235
        $customExtension->getAccessMapping($admin)->willReturn(
236
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
237
        );
238
        $admin->addExtension($customExtension->reveal());
239
        $admin->setSecurityHandler($securityHandler->reveal());
240
241
        $this->assertTrue($admin->hasAccess('custom_action'));
242
    }
243
244
    public function testHasAccessAllowsAccessEditAction(): void
245
    {
246
        $admin = new PostAdmin(
247
            'sonata.post.admin.post',
248
            'Application\Sonata\NewsBundle\Entity\Post',
249
            'Sonata\NewsBundle\Controller\PostAdminController'
250
        );
251
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
252
        $securityHandler->isGranted($admin, 'EDIT_ROLE', $admin)->willReturn(true);
253
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
254
        $customExtension->getAccessMapping($admin)->willReturn(
255
            ['edit_action' => ['EDIT_ROLE']]
256
        );
257
        $admin->addExtension($customExtension->reveal());
258
        $admin->setSecurityHandler($securityHandler->reveal());
259
260
        $this->assertTrue($admin->hasAccess('edit_action'));
261
    }
262
263
    /**
264
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChild
265
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::addChild
266
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChild
267
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::isChild
268
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChildren
269
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChildren
270
     */
271
    public function testChildren(): void
272
    {
273
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
274
        $this->assertFalse($postAdmin->hasChildren());
275
        $this->assertFalse($postAdmin->hasChild('comment'));
276
277
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
278
        $postAdmin->addChild($commentAdmin, 'post');
279
280
        $this->assertTrue($postAdmin->hasChildren());
281
        $this->assertTrue($postAdmin->hasChild('sonata.post.admin.comment'));
282
283
        $this->assertSame('sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getCode());
284
        $this->assertSame('sonata.post.admin.post|sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getBaseCodeRoute());
285
        $this->assertSame($postAdmin, $postAdmin->getChild('sonata.post.admin.comment')->getParent());
286
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
287
288
        $this->assertFalse($postAdmin->isChild());
289
        $this->assertTrue($commentAdmin->isChild());
290
291
        $this->assertSame(['sonata.post.admin.comment' => $commentAdmin], $postAdmin->getChildren());
292
    }
293
294
    /**
295
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configure
296
     */
297
    public function testConfigure(): void
298
    {
299
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
300
        $this->assertNotNull($admin->getUniqid());
301
302
        $admin->initialize();
303
        $this->assertNotNull($admin->getUniqid());
304
        $this->assertSame('Post', $admin->getClassnameLabel());
305
306
        $admin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
307
        $admin->setClassnameLabel('postcomment');
308
309
        $admin->initialize();
310
        $this->assertSame('postcomment', $admin->getClassnameLabel());
311
    }
312
313
    public function testConfigureWithValidParentAssociationMapping(): void
314
    {
315
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
316
        $admin->setParentAssociationMapping('Category');
317
318
        $admin->initialize();
319
        $this->assertSame('Category', $admin->getParentAssociationMapping());
320
    }
321
322
    public function provideGetBaseRoutePattern()
323
    {
324
        return [
325
            [
326
                'Application\Sonata\NewsBundle\Entity\Post',
327
                '/sonata/news/post',
328
            ],
329
            [
330
                'Application\Sonata\NewsBundle\Document\Post',
331
                '/sonata/news/post',
332
            ],
333
            [
334
                'MyApplication\MyBundle\Entity\Post',
335
                '/myapplication/my/post',
336
            ],
337
            [
338
                'MyApplication\MyBundle\Entity\Post\Category',
339
                '/myapplication/my/post-category',
340
            ],
341
            [
342
                'MyApplication\MyBundle\Entity\Product\Category',
343
                '/myapplication/my/product-category',
344
            ],
345
            [
346
                'MyApplication\MyBundle\Entity\Other\Product\Category',
347
                '/myapplication/my/other-product-category',
348
            ],
349
            [
350
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
351
                '/cmf/foo/menu',
352
            ],
353
            [
354
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
355
                '/cmf/foo/menu',
356
            ],
357
            [
358
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
359
                '/symfony/barbar/menu',
360
            ],
361
            [
362
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
363
                '/symfony/barbar/menu-item',
364
            ],
365
            [
366
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
367
                '/cmf/foo/menu',
368
            ],
369
            [
370
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
371
                '/cmf/foo/menu',
372
            ],
373
            [
374
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
375
                '/cmf/foo/menu',
376
            ],
377
            [
378
                'AppBundle\Entity\User',
379
                '/app/user',
380
            ],
381
            [
382
                'App\Entity\User',
383
                '/app/user',
384
            ],
385
        ];
386
    }
387
388
    /**
389
     * @dataProvider provideGetBaseRoutePattern
390
     */
391
    public function testGetBaseRoutePattern(string $objFqn, string $expected): void
392
    {
393
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
394
        $this->assertSame($expected, $admin->getBaseRoutePattern());
395
    }
396
397
    /**
398
     * @dataProvider provideGetBaseRoutePattern
399
     */
400
    public function testGetBaseRoutePatternWithChildAdmin(string $objFqn, string $expected): void
401
    {
402
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
403
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
404
        $commentAdmin->setParent($postAdmin);
405
406
        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
407
    }
408
409
    /**
410
     * @dataProvider provideGetBaseRoutePattern
411
     */
412
    public function testGetBaseRoutePatternWithTwoNestedChildAdmin(string $objFqn, string $expected): void
413
    {
414
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
415
        $commentAdmin = new CommentAdmin(
416
            'sonata.post.admin.comment',
417
            'Application\Sonata\NewsBundle\Entity\Comment',
418
            'Sonata\NewsBundle\Controller\CommentAdminController'
419
        );
420
        $commentVoteAdmin = new CommentVoteAdmin(
421
            'sonata.post.admin.comment_vote',
422
            'Application\Sonata\NewsBundle\Entity\CommentVote',
423
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
424
        );
425
        $commentAdmin->setParent($postAdmin);
426
        $commentVoteAdmin->setParent($commentAdmin);
427
428
        $this->assertSame($expected.'/{id}/comment/{childId}/commentvote', $commentVoteAdmin->getBaseRoutePattern());
429
    }
430
431
    public function testGetBaseRoutePatternWithSpecifedPattern(): void
432
    {
433
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostWithCustomRouteAdminController');
434
435
        $this->assertSame('/post-custom', $postAdmin->getBaseRoutePattern());
436
    }
437
438
    public function testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern(): void
439
    {
440
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
441
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
442
        $commentAdmin->setParent($postAdmin);
443
444
        $this->assertSame('/sonata/news/post/{id}/comment-custom', $commentAdmin->getBaseRoutePattern());
445
    }
446
447
    public function testGetBaseRoutePatternWithUnreconizedClassname(): void
448
    {
449
        $this->expectException(\RuntimeException::class);
450
451
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
452
        $admin->getBaseRoutePattern();
453
    }
454
455
    public function provideGetBaseRouteName()
456
    {
457
        return [
458
            [
459
                'Application\Sonata\NewsBundle\Entity\Post',
460
                'admin_sonata_news_post',
461
            ],
462
            [
463
                'Application\Sonata\NewsBundle\Document\Post',
464
                'admin_sonata_news_post',
465
            ],
466
            [
467
                'MyApplication\MyBundle\Entity\Post',
468
                'admin_myapplication_my_post',
469
            ],
470
            [
471
                'MyApplication\MyBundle\Entity\Post\Category',
472
                'admin_myapplication_my_post_category',
473
            ],
474
            [
475
                'MyApplication\MyBundle\Entity\Product\Category',
476
                'admin_myapplication_my_product_category',
477
            ],
478
            [
479
                'MyApplication\MyBundle\Entity\Other\Product\Category',
480
                'admin_myapplication_my_other_product_category',
481
            ],
482
            [
483
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
484
                'admin_cmf_foo_menu',
485
            ],
486
            [
487
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
488
                'admin_cmf_foo_menu',
489
            ],
490
            [
491
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
492
                'admin_symfony_barbar_menu',
493
            ],
494
            [
495
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
496
                'admin_symfony_barbar_menu_item',
497
            ],
498
            [
499
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
500
                'admin_cmf_foo_menu',
501
            ],
502
            [
503
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
504
                'admin_cmf_foo_menu',
505
            ],
506
            [
507
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
508
                'admin_cmf_foo_menu',
509
            ],
510
            [
511
                'AppBundle\Entity\User',
512
                'admin_app_user',
513
            ],
514
            [
515
                'App\Entity\User',
516
                'admin_app_user',
517
            ],
518
        ];
519
    }
520
521
    /**
522
     * @dataProvider provideGetBaseRouteName
523
     */
524
    public function testGetBaseRouteName(string $objFqn, string $expected): void
525
    {
526
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
527
528
        $this->assertSame($expected, $admin->getBaseRouteName());
529
    }
530
531
    /**
532
     * @group legacy
533
     * @expectedDeprecation Calling "addChild" without second argument is deprecated since sonata-project/admin-bundle 3.35 and will not be allowed in 4.0.
534
     * @dataProvider provideGetBaseRouteName
535
     */
536
    public function testGetBaseRouteNameWithChildAdmin(string $objFqn, string $expected): void
537
    {
538
        $routeGenerator = new DefaultRouteGenerator(
539
            $this->createMock(RouterInterface::class),
540
            new RoutesCache($this->cacheTempFolder, true)
541
        );
542
543
        $container = new Container();
544
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
545
546
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
547
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
548
        $container->set('sonata.post.admin.post', $postAdmin);
549
        $postAdmin->setConfigurationPool($pool);
550
        $postAdmin->setRouteBuilder($pathInfo);
551
        $postAdmin->setRouteGenerator($routeGenerator);
552
        $postAdmin->initialize();
553
554
        $commentAdmin = new CommentAdmin(
555
            'sonata.post.admin.comment',
556
            'Application\Sonata\NewsBundle\Entity\Comment',
557
            'Sonata\NewsBundle\Controller\CommentAdminController'
558
        );
559
        $container->set('sonata.post.admin.comment', $commentAdmin);
560
        $commentAdmin->setConfigurationPool($pool);
561
        $commentAdmin->setRouteBuilder($pathInfo);
562
        $commentAdmin->setRouteGenerator($routeGenerator);
563
        $commentAdmin->initialize();
564
565
        $postAdmin->addChild($commentAdmin, 'post');
566
567
        $commentVoteAdmin = new CommentVoteAdmin(
568
            'sonata.post.admin.comment_vote',
569
            'Application\Sonata\NewsBundle\Entity\CommentVote',
570
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
571
        );
572
573
        $container->set('sonata.post.admin.comment_vote', $commentVoteAdmin);
574
        $commentVoteAdmin->setConfigurationPool($pool);
575
        $commentVoteAdmin->setRouteBuilder($pathInfo);
576
        $commentVoteAdmin->setRouteGenerator($routeGenerator);
577
        $commentVoteAdmin->initialize();
578
579
        $commentAdmin->addChild($commentVoteAdmin);
580
        $pool->setAdminServiceIds([
581
            'sonata.post.admin.post',
582
            'sonata.post.admin.comment',
583
            'sonata.post.admin.comment_vote',
584
        ]);
585
586
        $this->assertSame($expected.'_comment', $commentAdmin->getBaseRouteName());
587
588
        $this->assertTrue($postAdmin->hasRoute('show'));
589
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
590
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.show'));
591
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment|sonata.post.admin.comment_vote.show'));
592
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment.list'));
593
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment|sonata.post.admin.comment_vote.list'));
594
        $this->assertFalse($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.edit'));
595
        $this->assertFalse($commentAdmin->hasRoute('edit'));
596
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
597
598
        /*
599
         * Test the route name from request
600
         */
601
        $postListRequest = new Request(
602
            [],
603
            [],
604
            [
605
                '_route' => $postAdmin->getBaseRouteName().'_list',
606
            ]
607
        );
608
609
        $postAdmin->setRequest($postListRequest);
610
        $commentAdmin->setRequest($postListRequest);
611
612
        $this->assertTrue($postAdmin->isCurrentRoute('list'));
613
        $this->assertFalse($postAdmin->isCurrentRoute('create'));
614
        $this->assertFalse($commentAdmin->isCurrentRoute('list'));
615
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('list'));
616
        $this->assertTrue($commentAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
617
        $this->assertFalse($commentAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
618
        $this->assertTrue($commentVoteAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
619
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
620
    }
621
622
    public function testGetBaseRouteNameWithUnreconizedClassname(): void
623
    {
624
        $this->expectException(\RuntimeException::class);
625
626
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
627
        $admin->getBaseRouteName();
628
    }
629
630
    public function testGetBaseRouteNameWithSpecifiedName(): void
631
    {
632
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
633
634
        $this->assertSame('post_custom', $postAdmin->getBaseRouteName());
635
    }
636
637
    public function testGetBaseRouteNameWithChildAdminAndWithSpecifiedName(): void
638
    {
639
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
640
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
641
        $commentAdmin->setParent($postAdmin);
642
643
        $this->assertSame('admin_sonata_news_post_comment_custom', $commentAdmin->getBaseRouteName());
644
    }
645
646
    public function testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName(): void
647
    {
648
        $postAdmin = new PostAdmin(
649
            'sonata.post.admin.post',
650
            'Application\Sonata\NewsBundle\Entity\Post',
651
            'Sonata\NewsBundle\Controller\PostAdminController'
652
        );
653
        $commentAdmin = new CommentWithCustomRouteAdmin(
654
            'sonata.post.admin.comment_with_custom_route',
655
            'Application\Sonata\NewsBundle\Entity\Comment',
656
            'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController'
657
        );
658
        $commentVoteAdmin = new CommentVoteAdmin(
659
            'sonata.post.admin.comment_vote',
660
            'Application\Sonata\NewsBundle\Entity\CommentVote',
661
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
662
        );
663
        $commentAdmin->setParent($postAdmin);
664
        $commentVoteAdmin->setParent($commentAdmin);
665
666
        $this->assertSame('admin_sonata_news_post_comment_custom_commentvote', $commentVoteAdmin->getBaseRouteName());
667
    }
668
669
    /**
670
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setUniqid
671
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getUniqid
672
     */
673
    public function testSetUniqid(): void
674
    {
675
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
676
677
        $uniqid = uniqid();
678
        $admin->setUniqid($uniqid);
679
680
        $this->assertSame($uniqid, $admin->getUniqid());
681
    }
682
683
    public function testToString(): void
684
    {
685
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
686
687
        $s = new \stdClass();
688
689
        $this->assertNotEmpty($admin->toString($s));
690
691
        $s = new FooToString();
692
        $this->assertSame('salut', $admin->toString($s));
693
694
        // To string method is implemented, but returns null
695
        $s = new FooToStringNull();
696
        $this->assertNotEmpty($admin->toString($s));
697
698
        $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...
699
    }
700
701
    public function testIsAclEnabled(): void
702
    {
703
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
704
705
        $this->assertFalse($postAdmin->isAclEnabled());
706
707
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
708
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
709
        $this->assertTrue($commentAdmin->isAclEnabled());
710
    }
711
712
    /**
713
     * @group legacy
714
     *
715
     * @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.
716
     *
717
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
718
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
719
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
720
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
721
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
722
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
723
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
724
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
725
     */
726
    public function testSubClass(): void
727
    {
728
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
729
        $admin = new PostAdmin(
730
            'sonata.post.admin.post',
731
            Post::class,
732
            'Sonata\NewsBundle\Controller\PostAdminController'
733
        );
734
        $this->assertFalse($admin->hasSubClass('test'));
735
        $this->assertFalse($admin->hasActiveSubClass());
736
        $this->assertCount(0, $admin->getSubClasses());
737
        $this->assertNull($admin->getActiveSubClass());
738
        $this->assertNull($admin->getActiveSubclassCode());
739
        $this->assertSame(Post::class, $admin->getClass());
740
741
        // Just for the record, if there is no inheritance set, the getSubject is not used
742
        // the getSubject can also lead to some issue
743
        $admin->setSubject(new BlogPost());
744
        $this->assertSame(BlogPost::class, $admin->getClass());
745
746
        $admin->setSubClasses([
747
            'extended1' => 'NewsBundle\Entity\PostExtended1',
748
            'extended2' => 'NewsBundle\Entity\PostExtended2',
749
        ]);
750
        $this->assertFalse($admin->hasSubClass('test'));
751
        $this->assertTrue($admin->hasSubClass('extended1'));
752
        $this->assertFalse($admin->hasActiveSubClass());
753
        $this->assertCount(2, $admin->getSubClasses());
754
        // NEXT_MAJOR: remove the following 2 `assertNull()` assertions
755
        $this->assertNull($admin->getActiveSubClass());
756
        $this->assertNull($admin->getActiveSubclassCode());
757
        $this->assertSame(
758
            BlogPost::class,
759
            $admin->getClass(),
760
            'When there is no subclass in the query the class parameter should be returned'
761
        );
762
763
        $request = new Request(['subclass' => 'extended1']);
764
        $admin->setRequest($request);
765
        $this->assertFalse($admin->hasSubClass('test'));
766
        $this->assertTrue($admin->hasSubClass('extended1'));
767
        $this->assertTrue($admin->hasActiveSubClass());
768
        $this->assertCount(2, $admin->getSubClasses());
769
        $this->assertSame(
770
            'NewsBundle\Entity\PostExtended1',
771
            $admin->getActiveSubClass(),
772
            'It should return the curently active sub class.'
773
        );
774
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
775
        $this->assertSame(
776
            'NewsBundle\Entity\PostExtended1',
777
            $admin->getClass(),
778
            'getClass() should return the name of the sub class when passed through a request query parameter.'
779
        );
780
781
        $request->query->set('subclass', 'inject');
782
783
        $this->assertNull($admin->getActiveSubclassCode());
784
        // NEXT_MAJOR: remove the previous `assertNull()` assertion and uncomment the following lines
785
        // $this->expectException(\LogicException::class);
786
        // $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
787
    }
788
789
    /**
790
     * @group legacy
791
     *
792
     * @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.
793
     */
794
    public function testNonExistantSubclass(): void
795
    {
796
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
797
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
798
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
799
800
        $admin->setRequest(new Request(['subclass' => 'inject']));
801
802
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
803
804
        $this->assertTrue($admin->hasActiveSubClass());
805
806
        $this->expectException(\RuntimeException::class);
807
808
        $admin->getActiveSubClass();
809
    }
810
811
    /**
812
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
813
     */
814
    public function testOnlyOneSubclassNeededToBeActive(): void
815
    {
816
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
817
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
818
        $request = new Request(['subclass' => 'extended1']);
819
        $admin->setRequest($request);
820
        $this->assertTrue($admin->hasActiveSubClass());
821
    }
822
823
    /**
824
     * @group legacy
825
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since sonata-project/admin-bundle 3.30 and will be removed in 4.0.
826
     */
827
    public function testAddSubClassIsDeprecated(): void
828
    {
829
        $admin = new PostAdmin(
830
            'sonata.post.admin.post',
831
            Post::class,
832
            'Sonata\NewsBundle\Controller\PostAdminController'
833
        );
834
        $admin->addSubClass('whatever');
835
    }
836
837
    /**
838
     * @group legacy
839
     */
840
    public function testGetPerPageOptions(): void
841
    {
842
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
843
844
        $perPageOptions = $admin->getPerPageOptions();
845
846
        foreach ($perPageOptions as $perPage) {
847
            $this->assertSame(0, $perPage % 4);
848
        }
849
850
        $admin->setPerPageOptions([500, 1000]);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...in::setPerPageOptions() has been deprecated with message: since sonata-project/admin-bundle 3.67, to be removed in 4.0. Set custom per page options.

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...
851
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
852
    }
853
854
    public function testGetLabelTranslatorStrategy(): void
855
    {
856
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
857
858
        $this->assertNull($admin->getLabelTranslatorStrategy());
859
860
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
861
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
862
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
863
    }
864
865
    public function testGetRouteBuilder(): void
866
    {
867
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
868
869
        $this->assertNull($admin->getRouteBuilder());
870
871
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
872
        $admin->setRouteBuilder($routeBuilder);
873
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
874
    }
875
876
    public function testGetMenuFactory(): void
877
    {
878
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
879
880
        $this->assertNull($admin->getMenuFactory());
881
882
        $menuFactory = $this->createMock(FactoryInterface::class);
883
        $admin->setMenuFactory($menuFactory);
884
        $this->assertSame($menuFactory, $admin->getMenuFactory());
885
    }
886
887
    public function testGetExtensions(): void
888
    {
889
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
890
891
        $this->assertSame([], $admin->getExtensions());
892
893
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
894
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
895
896
        $admin->addExtension($adminExtension1);
897
        $admin->addExtension($adminExtension2);
898
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
899
    }
900
901
    public function testGetFilterTheme(): void
902
    {
903
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
904
905
        $this->assertSame([], $admin->getFilterTheme());
906
907
        $admin->setFilterTheme(['FooTheme']);
908
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
909
    }
910
911
    public function testGetFormTheme(): void
912
    {
913
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
914
915
        $this->assertSame([], $admin->getFormTheme());
916
917
        $admin->setFormTheme(['FooTheme']);
918
919
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
920
    }
921
922
    public function testGetValidator(): void
923
    {
924
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
925
926
        $this->assertNull($admin->getValidator());
927
928
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
929
930
        $admin->setValidator($validator);
931
        $this->assertSame($validator, $admin->getValidator());
932
    }
933
934
    public function testGetSecurityHandler(): void
935
    {
936
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
937
938
        $this->assertNull($admin->getSecurityHandler());
939
940
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
941
        $admin->setSecurityHandler($securityHandler);
942
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
943
    }
944
945
    public function testGetSecurityInformation(): void
946
    {
947
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
948
949
        $this->assertSame([], $admin->getSecurityInformation());
950
951
        $securityInformation = [
952
            'GUEST' => ['VIEW', 'LIST'],
953
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
954
        ];
955
956
        $admin->setSecurityInformation($securityInformation);
957
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
958
    }
959
960
    public function testGetManagerType(): void
961
    {
962
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
963
964
        $this->assertNull($admin->getManagerType());
965
966
        $admin->setManagerType('foo_orm');
967
        $this->assertSame('foo_orm', $admin->getManagerType());
968
    }
969
970
    public function testGetModelManager(): void
971
    {
972
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
973
974
        $this->assertNull($admin->getModelManager());
975
976
        $modelManager = $this->createMock(ModelManagerInterface::class);
977
978
        $admin->setModelManager($modelManager);
979
        $this->assertSame($modelManager, $admin->getModelManager());
980
    }
981
982
    /**
983
     * NEXT_MAJOR: remove this method.
984
     *
985
     * @group legacy
986
     */
987
    public function testGetBaseCodeRoute(): void
988
    {
989
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
990
991
        $this->assertSame('', $admin->getBaseCodeRoute());
992
993
        $admin->setBaseCodeRoute('foo');
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...min::setBaseCodeRoute() has been deprecated with message: This method is deprecated since sonata-project/admin-bundle 3.24 and will be removed in 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...
994
        $this->assertSame('foo', $admin->getBaseCodeRoute());
995
    }
996
997
    // NEXT_MAJOR: uncomment this method.
998
    // public function testGetBaseCodeRoute()
999
    // {
1000
    //     $postAdmin = new PostAdmin(
1001
    //         'sonata.post.admin.post',
1002
    //         'NewsBundle\Entity\Post',
1003
    //         'Sonata\NewsBundle\Controller\PostAdminController'
1004
    //     );
1005
    //     $commentAdmin = new CommentAdmin(
1006
    //         'sonata.post.admin.comment',
1007
    //         'Application\Sonata\NewsBundle\Entity\Comment',
1008
    //         'Sonata\NewsBundle\Controller\CommentAdminController'
1009
    //     );
1010
    //
1011
    //     $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
1012
    //
1013
    //     $postAdmin->addChild($commentAdmin);
1014
    //
1015
    //     $this->assertSame(
1016
    //         'sonata.post.admin.post|sonata.post.admin.comment',
1017
    //         $commentAdmin->getBaseCodeRoute()
1018
    //     );
1019
    // }
1020
1021
    public function testGetRouteGenerator(): void
1022
    {
1023
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1024
1025
        $this->assertNull($admin->getRouteGenerator());
1026
1027
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1028
1029
        $admin->setRouteGenerator($routeGenerator);
1030
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1031
    }
1032
1033
    public function testGetConfigurationPool(): void
1034
    {
1035
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1036
1037
        $this->assertNull($admin->getConfigurationPool());
1038
1039
        $pool = $this->getMockBuilder(Pool::class)
1040
            ->disableOriginalConstructor()
1041
            ->getMock();
1042
1043
        $admin->setConfigurationPool($pool);
1044
        $this->assertSame($pool, $admin->getConfigurationPool());
1045
    }
1046
1047
    public function testGetShowBuilder(): void
1048
    {
1049
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1050
1051
        $this->assertNull($admin->getShowBuilder());
1052
1053
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1054
1055
        $admin->setShowBuilder($showBuilder);
1056
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1057
    }
1058
1059
    public function testGetListBuilder(): void
1060
    {
1061
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1062
1063
        $this->assertNull($admin->getListBuilder());
1064
1065
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1066
1067
        $admin->setListBuilder($listBuilder);
1068
        $this->assertSame($listBuilder, $admin->getListBuilder());
1069
    }
1070
1071
    public function testGetDatagridBuilder(): void
1072
    {
1073
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1074
1075
        $this->assertNull($admin->getDatagridBuilder());
1076
1077
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1078
1079
        $admin->setDatagridBuilder($datagridBuilder);
1080
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1081
    }
1082
1083
    public function testGetFormContractor(): void
1084
    {
1085
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1086
1087
        $this->assertNull($admin->getFormContractor());
1088
1089
        $formContractor = $this->createMock(FormContractorInterface::class);
1090
1091
        $admin->setFormContractor($formContractor);
1092
        $this->assertSame($formContractor, $admin->getFormContractor());
1093
    }
1094
1095
    public function testGetRequest(): void
1096
    {
1097
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1098
1099
        $this->assertFalse($admin->hasRequest());
1100
1101
        $request = new Request();
1102
1103
        $admin->setRequest($request);
1104
        $this->assertSame($request, $admin->getRequest());
1105
        $this->assertTrue($admin->hasRequest());
1106
    }
1107
1108
    public function testGetRequestWithException(): void
1109
    {
1110
        $this->expectException(\RuntimeException::class);
1111
        $this->expectExceptionMessage('The Request object has not been set');
1112
1113
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1114
        $admin->getRequest();
1115
    }
1116
1117
    public function testGetTranslationDomain(): void
1118
    {
1119
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1120
1121
        $this->assertSame('messages', $admin->getTranslationDomain());
1122
1123
        $admin->setTranslationDomain('foo');
1124
        $this->assertSame('foo', $admin->getTranslationDomain());
1125
    }
1126
1127
    /**
1128
     * @group legacy
1129
     */
1130
    public function testGetTranslator(): void
1131
    {
1132
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1133
1134
        $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...
1135
1136
        $translator = $this->createMock(TranslatorInterface::class);
1137
1138
        $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...
1139
        $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...
1140
    }
1141
1142
    public function testGetShowGroups(): void
1143
    {
1144
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1145
1146
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1147
        $this->assertFalse($admin->getShowGroups('sonata_deprecation_mute'));
1148
1149
        $groups = ['foo', 'bar', 'baz'];
1150
1151
        $admin->setShowGroups($groups);
1152
        $this->assertSame($groups, $admin->getShowGroups());
1153
    }
1154
1155
    public function testGetFormGroups(): void
1156
    {
1157
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1158
1159
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1160
        $this->assertFalse($admin->getFormGroups('sonata_deprecation_mute'));
1161
1162
        $groups = ['foo', 'bar', 'baz'];
1163
1164
        $admin->setFormGroups($groups);
1165
        $this->assertSame($groups, $admin->getFormGroups());
1166
    }
1167
1168
    public function testGetMaxPageLinks(): void
1169
    {
1170
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1171
1172
        $this->assertSame(25, $admin->getMaxPageLinks());
1173
1174
        $admin->setMaxPageLinks(14);
1175
        $this->assertSame(14, $admin->getMaxPageLinks());
1176
    }
1177
1178
    /**
1179
     * @group legacy
1180
     */
1181
    public function testGetMaxPerPage(): void
1182
    {
1183
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1184
1185
        $this->assertSame(32, $admin->getMaxPerPage());
1186
1187
        $admin->setMaxPerPage(94);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setMaxPerPage() has been deprecated with message: since sonata-project/admin-bundle 3.67, to be removed in 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...
1188
        $this->assertSame(94, $admin->getMaxPerPage());
1189
    }
1190
1191
    public function testGetLabel(): void
1192
    {
1193
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1194
1195
        $this->assertNull($admin->getLabel());
1196
1197
        $admin->setLabel('FooLabel');
1198
        $this->assertSame('FooLabel', $admin->getLabel());
1199
    }
1200
1201
    public function testGetBaseController(): void
1202
    {
1203
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1204
1205
        $this->assertSame('Sonata\NewsBundle\Controller\PostAdminController', $admin->getBaseControllerName());
1206
1207
        $admin->setBaseControllerName('Sonata\NewsBundle\Controller\FooAdminController');
1208
        $this->assertSame('Sonata\NewsBundle\Controller\FooAdminController', $admin->getBaseControllerName());
1209
    }
1210
1211
    public function testGetTemplates(): void
1212
    {
1213
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1214
1215
        $templates = [
1216
            'list' => '@FooAdmin/CRUD/list.html.twig',
1217
            'show' => '@FooAdmin/CRUD/show.html.twig',
1218
            'edit' => '@FooAdmin/CRUD/edit.html.twig',
1219
        ];
1220
1221
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1222
        $templateRegistry->getTemplates()->shouldBeCalled()->willReturn($templates);
1223
1224
        $admin->setTemplateRegistry($templateRegistry->reveal());
1225
1226
        $this->assertSame($templates, $admin->getTemplates());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...ctAdmin::getTemplates() has been deprecated with message: since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead

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...
1227
    }
1228
1229
    public function testGetTemplate1(): void
1230
    {
1231
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1232
1233
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1234
        $templateRegistry->getTemplate('edit')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/edit.html.twig');
1235
        $templateRegistry->getTemplate('show')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/show.html.twig');
1236
1237
        $admin->setTemplateRegistry($templateRegistry->reveal());
1238
1239
        $this->assertSame('@FooAdmin/CRUD/edit.html.twig', $admin->getTemplate('edit'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::getTemplate() has been deprecated with message: since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead

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...
1240
        $this->assertSame('@FooAdmin/CRUD/show.html.twig', $admin->getTemplate('show'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::getTemplate() has been deprecated with message: since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead

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...
1241
    }
1242
1243
    public function testGetIdParameter(): void
1244
    {
1245
        $postAdmin = new PostAdmin(
1246
            'sonata.post.admin.post',
1247
            'NewsBundle\Entity\Post',
1248
            'Sonata\NewsBundle\Controller\PostAdminController'
1249
        );
1250
1251
        $this->assertSame('id', $postAdmin->getIdParameter());
1252
        $this->assertFalse($postAdmin->isChild());
1253
1254
        $commentAdmin = new CommentAdmin(
1255
            'sonata.post.admin.comment',
1256
            'Application\Sonata\NewsBundle\Entity\Comment',
1257
            'Sonata\NewsBundle\Controller\CommentAdminController'
1258
        );
1259
        $commentAdmin->setParent($postAdmin);
1260
1261
        $this->assertTrue($commentAdmin->isChild());
1262
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1263
1264
        $commentVoteAdmin = new CommentVoteAdmin(
1265
            'sonata.post.admin.comment_vote',
1266
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1267
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
1268
        );
1269
        $commentVoteAdmin->setParent($commentAdmin);
1270
1271
        $this->assertTrue($commentVoteAdmin->isChild());
1272
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1273
    }
1274
1275
    public function testGetExportFormats(): void
1276
    {
1277
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1278
1279
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1280
    }
1281
1282
    public function testGetUrlsafeIdentifier(): void
1283
    {
1284
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1285
1286
        $model = new \stdClass();
1287
1288
        $modelManager = $this->createMock(ModelManagerInterface::class);
1289
        $modelManager->expects($this->once())
1290
            ->method('getUrlSafeIdentifier')
1291
            ->with($this->equalTo($model))
1292
            ->willReturn('foo');
1293
        $admin->setModelManager($modelManager);
1294
1295
        $this->assertSame('foo', $admin->getUrlSafeIdentifier($model));
1296
    }
1297
1298
    public function testDeterminedPerPageValue(): void
1299
    {
1300
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1301
1302
        $this->assertFalse($admin->determinedPerPageValue('foo'));
1303
        $this->assertFalse($admin->determinedPerPageValue(123));
1304
        $this->assertTrue($admin->determinedPerPageValue(16));
1305
    }
1306
1307
    public function testIsGranted(): void
1308
    {
1309
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1310
        $modelManager = $this->createStub(ModelManagerInterface::class);
1311
        $modelManager
1312
            ->method('getNormalizedIdentifier')
1313
            ->willReturnCallback(static function (?object $model = null): ?string {
1314
                return $model ? $model->id : null;
1315
            });
1316
1317
        $admin->setModelManager($modelManager);
1318
1319
        $entity1 = new \stdClass();
1320
        $entity1->id = '1';
1321
1322
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1323
        $securityHandler
1324
            ->expects($this->exactly(6))
1325
            ->method('isGranted')
1326
            ->willReturnCallback(static function (
1327
                AdminInterface $adminIn,
1328
                string $attributes,
1329
                ?object $object = null
1330
            ) use (
1331
                $admin,
1332
                $entity1
1333
            ): bool {
1334
                return $admin === $adminIn && 'FOO' === $attributes &&
1335
                    ($object === $admin || $object === $entity1);
1336
            });
1337
1338
        $admin->setSecurityHandler($securityHandler);
1339
1340
        $this->assertTrue($admin->isGranted('FOO'));
1341
        $this->assertTrue($admin->isGranted('FOO'));
1342
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1343
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1344
        $this->assertFalse($admin->isGranted('BAR'));
1345
        $this->assertFalse($admin->isGranted('BAR'));
1346
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1347
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1348
1349
        $entity2 = new \stdClass();
1350
        $entity2->id = '2';
1351
1352
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1353
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1354
1355
        $entity3 = new \stdClass();
1356
        $entity3->id = '3';
1357
1358
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1359
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1360
    }
1361
1362
    public function testSupportsPreviewMode(): void
1363
    {
1364
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1365
1366
        $this->assertFalse($admin->supportsPreviewMode());
1367
    }
1368
1369
    public function testGetPermissionsShow(): void
1370
    {
1371
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1372
1373
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1374
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1375
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1376
    }
1377
1378
    public function testShowIn(): void
1379
    {
1380
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1381
1382
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1383
        $securityHandler
1384
            ->method('isGranted')
1385
            ->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...
1386
                return $admin === $adminIn && $attributes === ['LIST'];
1387
            });
1388
1389
        $admin->setSecurityHandler($securityHandler);
1390
1391
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1392
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1393
        $this->assertTrue($admin->showIn('foo'));
1394
    }
1395
1396
    public function testGetObjectIdentifier(): void
1397
    {
1398
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1399
1400
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1401
    }
1402
1403
    /**
1404
     * @group legacy
1405
     */
1406
    public function testTrans(): void
1407
    {
1408
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1409
        $admin->setTranslationDomain('fooMessageDomain');
1410
1411
        $translator = $this->createMock(TranslatorInterface::class);
1412
        $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...
1413
1414
        $translator->expects($this->once())
1415
            ->method('trans')
1416
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1417
            ->willReturn('fooTranslated');
1418
1419
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1420
    }
1421
1422
    /**
1423
     * @group legacy
1424
     */
1425
    public function testTransWithMessageDomain(): void
1426
    {
1427
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1428
1429
        $translator = $this->createMock(TranslatorInterface::class);
1430
        $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...
1431
1432
        $translator->expects($this->once())
1433
            ->method('trans')
1434
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1435
            ->willReturn('fooTranslated');
1436
1437
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1438
    }
1439
1440
    /**
1441
     * @group legacy
1442
     */
1443
    public function testTransChoice(): void
1444
    {
1445
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1446
        $admin->setTranslationDomain('fooMessageDomain');
1447
1448
        $translator = $this->createMock(TranslatorInterface::class);
1449
        $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...
1450
1451
        $translator->expects($this->once())
1452
            ->method('transChoice')
1453
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1454
            ->willReturn('fooTranslated');
1455
1456
        $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...
1457
    }
1458
1459
    /**
1460
     * @group legacy
1461
     */
1462
    public function testTransChoiceWithMessageDomain(): void
1463
    {
1464
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1465
1466
        $translator = $this->createMock(TranslatorInterface::class);
1467
        $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...
1468
1469
        $translator->expects($this->once())
1470
            ->method('transChoice')
1471
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1472
            ->willReturn('fooTranslated');
1473
1474
        $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...
1475
    }
1476
1477
    public function testSetFilterPersister(): void
1478
    {
1479
        $admin = new class('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController') extends PostAdmin {
1480
            public function persistFilters(): bool
1481
            {
1482
                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...
1483
            }
1484
        };
1485
1486
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1487
1488
        $admin->setFilterPersister($filterPersister);
1489
        $this->assertTrue($admin->persistFilters());
1490
    }
1491
1492
    public function testGetRootCode(): void
1493
    {
1494
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1495
1496
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1497
1498
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1499
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1500
        $parentFieldDescription->expects($this->once())
1501
            ->method('getAdmin')
1502
            ->willReturn($parentAdmin);
1503
1504
        $this->assertFalse($admin->hasParentFieldDescription());
1505
        $admin->setParentFieldDescription($parentFieldDescription);
1506
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1507
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1508
    }
1509
1510
    public function testGetRoot(): void
1511
    {
1512
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1513
1514
        $this->assertSame($admin, $admin->getRoot());
1515
1516
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1517
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1518
        $parentFieldDescription->expects($this->once())
1519
            ->method('getAdmin')
1520
            ->willReturn($parentAdmin);
1521
1522
        $this->assertFalse($admin->hasParentFieldDescription());
1523
        $admin->setParentFieldDescription($parentFieldDescription);
1524
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1525
        $this->assertSame($parentAdmin, $admin->getRoot());
1526
    }
1527
1528
    public function testGetExportFields(): void
1529
    {
1530
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1531
1532
        $modelManager = $this->createMock(ModelManagerInterface::class);
1533
        $modelManager->expects($this->once())
1534
            ->method('getExportFields')
1535
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1536
            ->willReturn(['foo', 'bar']);
1537
1538
        $admin->setModelManager($modelManager);
1539
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1540
    }
1541
1542
    public function testGetPersistentParametersWithNoExtension(): void
1543
    {
1544
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1545
1546
        $this->assertEmpty($admin->getPersistentParameters());
1547
    }
1548
1549
    public function testGetPersistentParametersWithInvalidExtension(): void
1550
    {
1551
        $this->expectException(\RuntimeException::class);
1552
1553
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1554
1555
        $extension = $this->createMock(AdminExtensionInterface::class);
1556
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn(null);
1557
1558
        $admin->addExtension($extension);
1559
1560
        $admin->getPersistentParameters();
1561
    }
1562
1563
    public function testGetPersistentParametersWithValidExtension(): void
1564
    {
1565
        $expected = [
1566
            'context' => 'foobar',
1567
        ];
1568
1569
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1570
1571
        $extension = $this->createMock(AdminExtensionInterface::class);
1572
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1573
1574
        $admin->addExtension($extension);
1575
1576
        $this->assertSame($expected, $admin->getPersistentParameters());
1577
    }
1578
1579
    public function testGetNewInstanceForChildAdminWithParentValue(): void
1580
    {
1581
        $post = new PostWithSingleTag();
1582
1583
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1584
        $postAdmin->method('getObject')->willReturn($post);
1585
1586
        $formBuilder = $this->createMock(FormBuilderInterface::class);
1587
        $formBuilder->method('getForm')->willReturn(null);
1588
1589
        $tag = new Tag();
1590
1591
        $modelManager = $this->createMock(ModelManagerInterface::class);
1592
        $modelManager->method('getModelInstance')->willReturn($tag);
1593
1594
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1595
        $tagAdmin->setModelManager($modelManager);
1596
        $tagAdmin->setParent($postAdmin);
1597
1598
        $request = $this->createMock(Request::class);
1599
        $tagAdmin->setRequest($request);
1600
1601
        $configurationPool = $this->getMockBuilder(Pool::class)
1602
            ->disableOriginalConstructor()
1603
            ->getMock();
1604
1605
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1606
1607
        $tagAdmin->setConfigurationPool($configurationPool);
1608
1609
        $tag = $tagAdmin->getNewInstance();
1610
1611
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1612
        $this->assertCount(1, $tag->getPosts());
1613
        $this->assertContains($post, $tag->getPosts());
1614
    }
1615
1616
    public function testGetNewInstanceForChildAdminWithCollectionParentValue(): void
1617
    {
1618
        $post = new Post();
1619
1620
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1621
        $postAdmin->method('getObject')->willReturn($post);
1622
1623
        $formBuilder = $this->createMock(FormBuilderInterface::class);
1624
        $formBuilder->method('getForm')->willReturn(null);
1625
1626
        $tag = new Tag();
1627
1628
        $modelManager = $this->createMock(ModelManagerInterface::class);
1629
        $modelManager->method('getModelInstance')->willReturn($tag);
1630
1631
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1632
        $tagAdmin->setModelManager($modelManager);
1633
        $tagAdmin->setParent($postAdmin);
1634
1635
        $request = $this->createMock(Request::class);
1636
        $tagAdmin->setRequest($request);
1637
1638
        $configurationPool = $this->getMockBuilder(Pool::class)
1639
            ->disableOriginalConstructor()
1640
            ->getMock();
1641
1642
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1643
1644
        $tagAdmin->setConfigurationPool($configurationPool);
1645
1646
        $tag = $tagAdmin->getNewInstance();
1647
1648
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1649
        $this->assertCount(1, $tag->getPosts());
1650
        $this->assertContains($post, $tag->getPosts());
1651
    }
1652
1653
    public function testGetNewInstanceForEmbededAdminWithCollectionParentValue(): void
1654
    {
1655
        $post = new Post();
1656
1657
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1658
        $postAdmin->method('getObject')->willReturn($post);
1659
1660
        $formBuilder = $this->createMock(FormBuilderInterface::class);
1661
        $formBuilder->method('getForm')->willReturn(null);
1662
1663
        $parentField = $this->createMock(FieldDescriptionInterface::class);
1664
        $parentField->method('getAdmin')->willReturn($postAdmin);
1665
        $parentField->method('getParentAssociationMappings')->willReturn([]);
1666
        $parentField->method('getAssociationMapping')->willReturn(['fieldName' => 'tag']);
1667
1668
        $tag = new Tag();
1669
1670
        $modelManager = $this->createMock(ModelManagerInterface::class);
1671
        $modelManager->method('getModelInstance')->willReturn($tag);
1672
1673
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1674
        $tagAdmin->setModelManager($modelManager);
1675
        $tagAdmin->setParentFieldDescription($parentField);
1676
1677
        $request = $this->createMock(Request::class);
1678
        $tagAdmin->setRequest($request);
1679
1680
        $configurationPool = $this->getMockBuilder(Pool::class)
1681
            ->disableOriginalConstructor()
1682
            ->getMock();
1683
1684
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1685
1686
        $tagAdmin->setConfigurationPool($configurationPool);
1687
1688
        $tag = $tagAdmin->getNewInstance();
1689
1690
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1691
        $this->assertCount(1, $tag->getPosts());
1692
        $this->assertContains($post, $tag->getPosts());
1693
    }
1694
1695
    public function testFormAddPostSubmitEventForPreValidation(): void
1696
    {
1697
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1698
        $object = new \stdClass();
1699
1700
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1701
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1702
1703
        $validator = $this->createMock(ValidatorInterface::class);
1704
        $validator
1705
                ->method('getMetadataFor')
1706
                ->willReturn($this->createMock(MemberMetadata::class));
1707
        $modelAdmin->setValidator($validator);
1708
1709
        $modelManager = $this->createMock(ModelManagerInterface::class);
1710
        $modelManager
1711
            ->method('getNewFieldDescriptionInstance')
1712
            ->willReturn(new FieldDescription());
1713
        $modelAdmin->setModelManager($modelManager);
1714
1715
        // a Admin class to test that preValidate is called
1716
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1717
        $testAdminPreValidate->expects($this->once())
1718
                ->method('preValidate')
1719
                ->with($this->identicalTo($object));
1720
1721
        $event = $this->createMock(FormEvent::class);
1722
        $event
1723
                ->method('getData')
1724
                ->willReturn($object);
1725
1726
        $formBuild = $this->createMock(FormBuilder::class);
1727
        $formBuild->expects($this->once())
1728
                ->method('addEventListener')
1729
                ->with(
1730
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1731
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1732
                        if (\is_callable($callback)) {
1733
                            $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...
1734
                            $closure($event);
1735
1736
                            return true;
1737
                        }
1738
1739
                        return false;
1740
                    }),
1741
                    $this->greaterThan(0)
1742
                );
1743
1744
        $formContractor = $this->createMock(FormContractorInterface::class);
1745
        $formContractor
1746
                ->method('getDefaultOptions')
1747
                ->willReturn([]);
1748
        $formContractor
1749
                ->method('getFormBuilder')
1750
                ->willReturn($formBuild);
1751
1752
        $modelAdmin->setFormContractor($formContractor);
1753
        $modelAdmin->setSubject($object);
1754
        $modelAdmin->defineFormBuilder($formBuild);
1755
        $modelAdmin->getForm();
1756
    }
1757
1758
    public function testRemoveFieldFromFormGroup(): void
1759
    {
1760
        $formGroups = [
1761
            'foobar' => [
1762
                'fields' => [
1763
                    'foo' => 'foo',
1764
                    'bar' => 'bar',
1765
                ],
1766
            ],
1767
        ];
1768
1769
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1770
        $admin->setFormGroups($formGroups);
1771
1772
        $admin->removeFieldFromFormGroup('foo');
1773
        $this->assertSame($admin->getFormGroups(), [
1774
            'foobar' => [
1775
                'fields' => [
1776
                    'bar' => 'bar',
1777
                ],
1778
            ],
1779
        ]);
1780
1781
        $admin->removeFieldFromFormGroup('bar');
1782
        $this->assertSame($admin->getFormGroups(), []);
1783
    }
1784
1785
    public function testGetFilterParameters(): void
1786
    {
1787
        $authorId = uniqid();
1788
1789
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1790
1791
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1792
        $commentAdmin->setParentAssociationMapping('post.author');
1793
        $commentAdmin->setParent($postAdmin);
1794
1795
        $request = $this->createMock(Request::class);
1796
        $query = $this->createMock(ParameterBag::class);
1797
        $query
1798
            ->method('get')
1799
            ->willReturn([
1800
                'filter' => [
1801
                    '_page' => '1',
1802
                    '_per_page' => '32',
1803
                ],
1804
            ]);
1805
1806
        $request->query = $query;
1807
        $request
1808
            ->method('get')
1809
            ->willReturn($authorId);
1810
1811
        $commentAdmin->setRequest($request);
1812
1813
        $modelManager = $this->createMock(ModelManagerInterface::class);
1814
        $modelManager
1815
            ->method('getDefaultSortValues')
1816
            ->willReturn([]);
1817
1818
        $commentAdmin->setModelManager($modelManager);
1819
1820
        $parameters = $commentAdmin->getFilterParameters();
1821
1822
        $this->assertTrue(isset($parameters['post__author']));
1823
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1824
    }
1825
1826
    public function testGetFilterFieldDescription(): void
1827
    {
1828
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1829
1830
        $fooFieldDescription = new FieldDescription();
1831
        $barFieldDescription = new FieldDescription();
1832
        $bazFieldDescription = new FieldDescription();
1833
1834
        $modelManager = $this->createMock(ModelManagerInterface::class);
1835
        $modelManager->expects($this->exactly(3))
1836
            ->method('getNewFieldDescriptionInstance')
1837
            ->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...
1838
                switch ($name) {
1839
                    case 'foo':
1840
                        $fieldDescription = $fooFieldDescription;
1841
1842
                        break;
1843
1844
                    case 'bar':
1845
                        $fieldDescription = $barFieldDescription;
1846
1847
                        break;
1848
1849
                    case 'baz':
1850
                        $fieldDescription = $bazFieldDescription;
1851
1852
                        break;
1853
1854
                    default:
1855
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1856
                        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...
1857
                }
1858
1859
                $fieldDescription->setName($name);
1860
1861
                return $fieldDescription;
1862
            });
1863
1864
        $modelAdmin->setModelManager($modelManager);
1865
1866
        $pager = $this->createMock(PagerInterface::class);
1867
1868
        $datagrid = $this->createMock(DatagridInterface::class);
1869
        $datagrid->expects($this->once())
1870
            ->method('getPager')
1871
            ->willReturn($pager);
1872
1873
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1874
        $datagridBuilder->expects($this->once())
1875
            ->method('getBaseDatagrid')
1876
            ->with($this->identicalTo($modelAdmin), [])
1877
            ->willReturn($datagrid);
1878
1879
        $datagridBuilder->expects($this->exactly(3))
1880
            ->method('addFilter')
1881
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1882
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1883
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1884
            });
1885
1886
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1887
1888
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1889
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1890
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1891
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1892
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1893
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1894
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1895
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1896
    }
1897
1898
    public function testGetSubjectNoRequest(): void
1899
    {
1900
        $modelManager = $this->createMock(ModelManagerInterface::class);
1901
        $modelManager
1902
            ->expects($this->never())
1903
            ->method('find');
1904
1905
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1906
        $admin->setModelManager($modelManager);
1907
1908
        $this->assertFalse($admin->hasSubject());
1909
    }
1910
1911
    public function testGetSideMenu(): void
1912
    {
1913
        $item = $this->createMock(ItemInterface::class);
1914
        $item
1915
            ->expects($this->once())
1916
            ->method('setChildrenAttribute')
1917
            ->with('class', 'nav navbar-nav');
1918
        $item
1919
            ->expects($this->once())
1920
            ->method('setExtra')
1921
            ->with('translation_domain', 'foo_bar_baz');
1922
1923
        $menuFactory = $this->createMock(FactoryInterface::class);
1924
        $menuFactory
1925
            ->expects($this->once())
1926
            ->method('createItem')
1927
            ->willReturn($item);
1928
1929
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1930
        $modelAdmin->setMenuFactory($menuFactory);
1931
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1932
1933
        $modelAdmin->getSideMenu('foo');
1934
    }
1935
1936
    /**
1937
     * @return array
1938
     */
1939
    public function provideGetSubject()
1940
    {
1941
        return [
1942
            [23],
1943
            ['azerty'],
1944
            ['4f69bbb5f14a13347f000092'],
1945
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1946
            ['123'.AdapterInterface::ID_SEPARATOR.'my_type'], // composite keys are supported
1947
        ];
1948
    }
1949
1950
    /**
1951
     * @dataProvider provideGetSubject
1952
     */
1953
    public function testGetSubjectFailed($id): void
1954
    {
1955
        $modelManager = $this->createMock(ModelManagerInterface::class);
1956
        $modelManager
1957
            ->expects($this->once())
1958
            ->method('find')
1959
            ->with('NewsBundle\Entity\Post', $id)
1960
            ->willReturn(null); // entity not found
1961
1962
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1963
        $admin->setModelManager($modelManager);
1964
1965
        $admin->setRequest(new Request(['id' => $id]));
1966
        $this->assertFalse($admin->hasSubject());
1967
    }
1968
1969
    /**
1970
     * @dataProvider provideGetSubject
1971
     */
1972
    public function testGetSubject($id): void
1973
    {
1974
        $model = new Post();
1975
1976
        $modelManager = $this->createMock(ModelManagerInterface::class);
1977
        $modelManager
1978
            ->expects($this->once())
1979
            ->method('find')
1980
            ->with('NewsBundle\Entity\Post', $id)
1981
            ->willReturn($model);
1982
1983
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1984
        $admin->setModelManager($modelManager);
1985
1986
        $admin->setRequest(new Request(['id' => $id]));
1987
        $this->assertTrue($admin->hasSubject());
1988
        $this->assertSame($model, $admin->getSubject());
1989
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
1990
    }
1991
1992
    public function testGetSubjectWithParentDescription(): void
1993
    {
1994
        $adminId = 1;
1995
1996
        $comment = new Comment();
1997
1998
        $modelManager = $this->createMock(ModelManagerInterface::class);
1999
        $modelManager
2000
            ->method('find')
2001
            ->with('NewsBundle\Entity\Comment', $adminId)
2002
            ->willReturn($comment);
2003
2004
        $request = new Request(['id' => $adminId]);
2005
2006
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2007
        $postAdmin->setRequest($request);
2008
2009
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
2010
        $commentAdmin->setRequest($request);
2011
        $commentAdmin->setModelManager($modelManager);
2012
2013
        $this->assertTrue($commentAdmin->hasSubject());
2014
        $this->assertSame($comment, $commentAdmin->getSubject());
2015
2016
        $commentAdmin->setSubject(null);
2017
        $commentAdmin->setParentFieldDescription(new FieldDescription());
2018
2019
        $this->assertFalse($commentAdmin->hasSubject());
2020
    }
2021
2022
    /**
2023
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2024
     */
2025
    public function testGetActionButtonsList(): void
2026
    {
2027
        $expected = [
2028
            'create' => [
2029
                'template' => 'Foo.html.twig',
2030
            ],
2031
        ];
2032
2033
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2034
2035
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2036
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
2037
2038
        $admin->setTemplateRegistry($templateRegistry->reveal());
2039
2040
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2041
        $securityHandler
2042
            ->expects($this->once())
2043
            ->method('isGranted')
2044
            ->with($admin, 'CREATE', $admin)
2045
            ->willReturn(true);
2046
        $admin->setSecurityHandler($securityHandler);
2047
2048
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2049
        $routeGenerator
2050
            ->expects($this->once())
2051
            ->method('hasAdminRoute')
2052
            ->with($admin, 'create')
2053
            ->willReturn(true);
2054
        $admin->setRouteGenerator($routeGenerator);
2055
2056
        $this->assertSame($expected, $admin->getActionButtons('list', null));
2057
    }
2058
2059
    /**
2060
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2061
     */
2062
    public function testGetActionButtonsListCreateDisabled(): void
2063
    {
2064
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2065
2066
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2067
        $securityHandler
2068
            ->expects($this->once())
2069
            ->method('isGranted')
2070
            ->with($admin, 'CREATE', $admin)
2071
            ->willReturn(false);
2072
        $admin->setSecurityHandler($securityHandler);
2073
2074
        $this->assertSame([], $admin->getActionButtons('list', null));
2075
    }
2076
2077
    /**
2078
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
2079
     */
2080
    public function testGetBatchActions(): void
2081
    {
2082
        $expected = [
2083
            'delete' => [
2084
                'label' => 'action_delete',
2085
                'translation_domain' => 'SonataAdminBundle',
2086
                'ask_confirmation' => true, // by default always true
2087
            ],
2088
            'foo' => [
2089
                'label' => 'action_foo',
2090
                'translation_domain' => 'SonataAdminBundle',
2091
            ],
2092
            'bar' => [
2093
                'label' => 'batch.label_bar',
2094
                'translation_domain' => 'SonataAdminBundle',
2095
            ],
2096
            'baz' => [
2097
                'label' => 'action_baz',
2098
                'translation_domain' => 'AcmeAdminBundle',
2099
            ],
2100
        ];
2101
2102
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2103
2104
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
2105
        $labelTranslatorStrategy
2106
            ->method('getLabel')
2107
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2108
                return $context.'.'.$type.'_'.$label;
2109
            });
2110
2111
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2112
        $admin->setRouteBuilder($pathInfo);
2113
        $admin->setTranslationDomain('SonataAdminBundle');
2114
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
2115
2116
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2117
        $routeGenerator
2118
            ->expects($this->once())
2119
            ->method('hasAdminRoute')
2120
            ->with($admin, 'delete')
2121
            ->willReturn(true);
2122
        $admin->setRouteGenerator($routeGenerator);
2123
2124
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2125
        $securityHandler
2126
            ->method('isGranted')
2127
            ->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...
2128
                return $admin === $adminIn && 'DELETE' === $attributes;
2129
            });
2130
        $admin->setSecurityHandler($securityHandler);
2131
2132
        $this->assertSame($expected, $admin->getBatchActions());
2133
    }
2134
2135
    /**
2136
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2137
     */
2138
    public function testShowMosaicButton(): void
2139
    {
2140
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2141
        $listModes = $admin->getListModes();
2142
2143
        $admin->showMosaicButton(true);
2144
2145
        $this->assertSame($listModes, $admin->getListModes());
2146
    }
2147
2148
    /**
2149
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2150
     */
2151
    public function testShowMosaicButtonHideMosaic(): void
2152
    {
2153
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2154
        $listModes = $admin->getListModes();
2155
        $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...
2156
2157
        $admin->showMosaicButton(false);
2158
2159
        $this->assertSame($expected, $admin->getListModes());
2160
    }
2161
2162
    /**
2163
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2164
     * @dataProvider provideGetBaseRouteName
2165
     */
2166
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2167
    {
2168
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2169
2170
        $routeGenerator = new DefaultRouteGenerator(
2171
            $this->createMock(RouterInterface::class),
2172
            new RoutesCache($this->cacheTempFolder, true)
2173
        );
2174
2175
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
2176
        $admin->setRouteBuilder($pathInfo);
2177
        $admin->setRouteGenerator($routeGenerator);
2178
        $admin->initialize();
2179
2180
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2181
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2182
2183
        $admin->setTemplateRegistry($templateRegistry->reveal());
2184
2185
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2186
        $securityHandler
2187
            ->method('isGranted')
2188
            ->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...
2189
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2190
            });
2191
2192
        $admin->setSecurityHandler($securityHandler);
2193
2194
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2195
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2196
    }
2197
2198
    public function testDefaultFilters(): void
2199
    {
2200
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2201
2202
        $subjectId = uniqid();
2203
2204
        $request = $this->createMock(Request::class);
2205
        $query = $this->createMock(ParameterBag::class);
2206
        $query
2207
            ->method('get')
2208
            ->with($this->equalTo('filter'))
2209
            ->willReturn([
2210
                'a' => [
2211
                    'value' => 'b',
2212
                ],
2213
                'foo' => [
2214
                    'type' => '1',
2215
                    'value' => 'bar',
2216
                ],
2217
                'baz' => [
2218
                    'type' => '5',
2219
                    'value' => 'test',
2220
                ],
2221
            ]);
2222
        $request->query = $query;
2223
2224
        $request
2225
            ->method('get')
2226
            ->willReturn($subjectId);
2227
2228
        $admin->setRequest($request);
2229
2230
        $modelManager = $this->createMock(ModelManagerInterface::class);
2231
        $modelManager
2232
            ->method('getDefaultSortValues')
2233
            ->willReturn([]);
2234
2235
        $admin->setModelManager($modelManager);
2236
2237
        $this->assertSame([
2238
            '_page' => 1,
2239
            '_per_page' => 32,
2240
            'foo' => [
2241
                'type' => '1',
2242
                'value' => 'bar',
2243
            ],
2244
            'baz' => [
2245
                'type' => '5',
2246
                'value' => 'test',
2247
            ],
2248
            'a' => [
2249
                'value' => 'b',
2250
            ],
2251
        ], $admin->getFilterParameters());
2252
2253
        $this->assertTrue($admin->isDefaultFilter('foo'));
2254
        $this->assertFalse($admin->isDefaultFilter('bar'));
2255
        $this->assertFalse($admin->isDefaultFilter('a'));
2256
    }
2257
2258
    /**
2259
     * @group legacy
2260
     */
2261
    public function testDefaultBreadcrumbsBuilder(): void
2262
    {
2263
        $container = $this->createMock(ContainerInterface::class);
2264
        $container->expects($this->once())
2265
            ->method('getParameter')
2266
            ->with('sonata.admin.configuration.breadcrumbs')
2267
            ->willReturn([]);
2268
2269
        $pool = $this->getMockBuilder(Pool::class)
2270
            ->disableOriginalConstructor()
2271
            ->getMock();
2272
        $pool->expects($this->once())
2273
            ->method('getContainer')
2274
            ->willReturn($container);
2275
2276
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2277
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2278
        ], '', true, true, true, ['getConfigurationPool']);
2279
        $admin->expects($this->once())
2280
            ->method('getConfigurationPool')
2281
            ->willReturn($pool);
2282
2283
        $this->assertInstanceOf(BreadcrumbsBuilder::class, $admin->getBreadcrumbsBuilder());
2284
    }
2285
2286
    /**
2287
     * @group legacy
2288
     */
2289
    public function testBreadcrumbsBuilderSetter(): void
2290
    {
2291
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2292
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2293
        ]);
2294
        $this->assertSame($admin, $admin->setBreadcrumbsBuilder($builder = $this->createMock(
2295
            BreadcrumbsBuilderInterface::class
2296
        )));
2297
        $this->assertSame($builder, $admin->getBreadcrumbsBuilder());
2298
    }
2299
2300
    /**
2301
     * @group legacy
2302
     */
2303
    public function testGetBreadcrumbs(): void
2304
    {
2305
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2306
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2307
        ]);
2308
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2309
        $action = 'myaction';
2310
        $builder->getBreadcrumbs($admin, $action)->shouldBeCalled();
2311
        $admin->setBreadcrumbsBuilder($builder->reveal())->getBreadcrumbs($action);
2312
    }
2313
2314
    /**
2315
     * @group legacy
2316
     */
2317
    public function testBuildBreadcrumbs(): void
2318
    {
2319
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2320
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2321
        ]);
2322
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2323
        $action = 'myaction';
2324
        $menu = $this->createMock(ItemInterface::class);
2325
        $builder->buildBreadcrumbs($admin, $action, $menu)
2326
            ->shouldBeCalledTimes(1)
2327
            ->willReturn($menu);
2328
        $admin->setBreadcrumbsBuilder($builder->reveal());
2329
2330
        /* check the called is proxied only once */
2331
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2332
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2333
    }
2334
2335
    /**
2336
     * NEXT_MAJOR: remove this method.
2337
     *
2338
     * @group legacy
2339
     */
2340
    public function testCreateQueryLegacyCallWorks(): void
2341
    {
2342
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2343
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2344
        ]);
2345
        $query = $this->createMock(ProxyQueryInterface::class);
2346
        $modelManager = $this->createMock(ModelManagerInterface::class);
2347
        $modelManager->expects($this->once())
2348
            ->method('createQuery')
2349
            ->with('My\Class')
2350
            ->willReturn($query);
2351
2352
        $admin->setModelManager($modelManager);
2353
        $this->assertSame($query, $admin->createQuery('list'));
2354
    }
2355
2356
    public function testGetDataSourceIterator(): void
2357
    {
2358
        $datagrid = $this->createMock(DatagridInterface::class);
2359
        $datagrid->method('buildPager');
2360
2361
        $modelManager = $this->createMock(ModelManagerInterface::class);
2362
        $modelManager->method('getExportFields')->willReturn([
2363
            'field',
2364
            'foo',
2365
            'bar',
2366
        ]);
2367
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2368
            ->with($this->equalTo($datagrid), $this->equalTo([
2369
                'Feld' => 'field',
2370
                1 => 'foo',
2371
                2 => 'bar',
2372
            ]));
2373
2374
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2375
            ->disableOriginalConstructor()
2376
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2377
            ->getMockForAbstractClass();
2378
        $admin->method('getDatagrid')->willReturn($datagrid);
2379
        $admin->setModelManager($modelManager);
2380
2381
        $admin
2382
            ->method('getTranslationLabel')
2383
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2384
                return $context.'.'.$type.'_'.$label;
2385
            });
2386
        $admin
2387
            ->method('trans')
2388
            ->willReturnCallback(static function (string $label): string {
2389
                if ('export.label_field' === $label) {
2390
                    return 'Feld';
2391
                }
2392
2393
                return $label;
2394
            });
2395
2396
        $admin->getDataSourceIterator();
2397
    }
2398
2399
    public function testCircularChildAdmin(): void
2400
    {
2401
        $this->expectException(\RuntimeException::class);
2402
        $this->expectExceptionMessage(
2403
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2404
        );
2405
2406
        $postAdmin = new PostAdmin(
2407
            'sonata.post.admin.post',
2408
            'Application\Sonata\NewsBundle\Entity\Post',
2409
            'Sonata\NewsBundle\Controller\PostAdminController'
2410
        );
2411
        $commentAdmin = new CommentAdmin(
2412
            'sonata.post.admin.comment',
2413
            'Application\Sonata\NewsBundle\Entity\Comment',
2414
            'Sonata\NewsBundle\Controller\CommentAdminController'
2415
        );
2416
        $postAdmin->addChild($commentAdmin, 'post');
2417
        $commentAdmin->addChild($postAdmin, 'comment');
2418
    }
2419
2420
    public function testCircularChildAdminTripleLevel(): void
2421
    {
2422
        $this->expectException(\RuntimeException::class);
2423
        $this->expectExceptionMessage(
2424
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2425
        );
2426
2427
        $postAdmin = new PostAdmin(
2428
            'sonata.post.admin.post',
2429
            'Application\Sonata\NewsBundle\Entity\Post',
2430
            'Sonata\NewsBundle\Controller\PostAdminController'
2431
        );
2432
        $commentAdmin = new CommentAdmin(
2433
            'sonata.post.admin.comment',
2434
            'Application\Sonata\NewsBundle\Entity\Comment',
2435
            'Sonata\NewsBundle\Controller\CommentAdminController'
2436
        );
2437
        $commentVoteAdmin = new CommentVoteAdmin(
2438
            'sonata.post.admin.comment_vote',
2439
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2440
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2441
        );
2442
        $postAdmin->addChild($commentAdmin, 'post');
2443
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2444
        $commentVoteAdmin->addChild($postAdmin, 'post');
2445
    }
2446
2447
    public function testCircularChildAdminWithItself(): void
2448
    {
2449
        $this->expectException(\RuntimeException::class);
2450
        $this->expectExceptionMessage(
2451
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2452
        );
2453
2454
        $postAdmin = new PostAdmin(
2455
            'sonata.post.admin.post',
2456
            'Application\Sonata\NewsBundle\Entity\Post',
2457
            'Sonata\NewsBundle\Controller\PostAdminController'
2458
        );
2459
        $postAdmin->addChild($postAdmin);
2460
    }
2461
2462
    public function testGetRootAncestor(): void
2463
    {
2464
        $postAdmin = new PostAdmin(
2465
            'sonata.post.admin.post',
2466
            'Application\Sonata\NewsBundle\Entity\Post',
2467
            'Sonata\NewsBundle\Controller\PostAdminController'
2468
        );
2469
        $commentAdmin = new CommentAdmin(
2470
            'sonata.post.admin.comment',
2471
            'Application\Sonata\NewsBundle\Entity\Comment',
2472
            'Sonata\NewsBundle\Controller\CommentAdminController'
2473
        );
2474
        $commentVoteAdmin = new CommentVoteAdmin(
2475
            'sonata.post.admin.comment_vote',
2476
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2477
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2478
        );
2479
2480
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2481
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2482
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2483
2484
        $postAdmin->addChild($commentAdmin, 'post');
2485
2486
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2487
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2488
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2489
2490
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2491
2492
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2493
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2494
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2495
    }
2496
2497
    public function testGetChildDepth(): void
2498
    {
2499
        $postAdmin = new PostAdmin(
2500
            'sonata.post.admin.post',
2501
            'Application\Sonata\NewsBundle\Entity\Post',
2502
            'Sonata\NewsBundle\Controller\PostAdminController'
2503
        );
2504
        $commentAdmin = new CommentAdmin(
2505
            'sonata.post.admin.comment',
2506
            'Application\Sonata\NewsBundle\Entity\Comment',
2507
            'Sonata\NewsBundle\Controller\CommentAdminController'
2508
        );
2509
        $commentVoteAdmin = new CommentVoteAdmin(
2510
            'sonata.post.admin.comment_vote',
2511
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2512
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2513
        );
2514
2515
        $this->assertSame(0, $postAdmin->getChildDepth());
2516
        $this->assertSame(0, $commentAdmin->getChildDepth());
2517
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2518
2519
        $postAdmin->addChild($commentAdmin, 'post');
2520
2521
        $this->assertSame(0, $postAdmin->getChildDepth());
2522
        $this->assertSame(1, $commentAdmin->getChildDepth());
2523
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2524
2525
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2526
2527
        $this->assertSame(0, $postAdmin->getChildDepth());
2528
        $this->assertSame(1, $commentAdmin->getChildDepth());
2529
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2530
    }
2531
2532
    public function testGetCurrentLeafChildAdmin(): void
2533
    {
2534
        $postAdmin = new PostAdmin(
2535
            'sonata.post.admin.post',
2536
            'Application\Sonata\NewsBundle\Entity\Post',
2537
            'Sonata\NewsBundle\Controller\PostAdminController'
2538
        );
2539
        $commentAdmin = new CommentAdmin(
2540
            'sonata.post.admin.comment',
2541
            'Application\Sonata\NewsBundle\Entity\Comment',
2542
            'Sonata\NewsBundle\Controller\CommentAdminController'
2543
        );
2544
        $commentVoteAdmin = new CommentVoteAdmin(
2545
            'sonata.post.admin.comment_vote',
2546
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2547
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2548
        );
2549
2550
        $postAdmin->addChild($commentAdmin, 'post');
2551
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2552
2553
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2554
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2555
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2556
2557
        $commentAdmin->setCurrentChild(true);
2558
2559
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2560
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2561
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2562
2563
        $commentVoteAdmin->setCurrentChild(true);
2564
2565
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2566
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2567
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2568
    }
2569
2570
    public function testAdminWithoutControllerName(): void
2571
    {
2572
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', null);
2573
2574
        $this->assertNull($admin->getBaseControllerName());
2575
    }
2576
2577
    public function testAdminAvoidInifiniteLoop(): void
2578
    {
2579
        $this->expectNotToPerformAssertions();
2580
2581
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2582
2583
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2584
        $admin->setSubject(new \stdClass());
2585
2586
        $admin->setFormContractor(new FormContractor($formFactory));
2587
2588
        $admin->setShowBuilder(new ShowBuilder());
2589
2590
        $admin->setListBuilder(new ListBuilder());
2591
2592
        $pager = $this->createStub(PagerInterface::class);
2593
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2594
2595
        $validator = $this->createMock(ValidatorInterface::class);
2596
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2597
        $admin->setValidator($validator);
2598
2599
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2600
        $admin->setRouteGenerator($routeGenerator);
2601
2602
        $admin->getForm();
2603
        $admin->getShow();
2604
        $admin->getList();
2605
        $admin->getDatagrid();
2606
    }
2607
2608
    /**
2609
     * NEXT_MAJOR: Remove this test and its data provider.
2610
     *
2611
     * @group legacy
2612
     *
2613
     * @dataProvider getDeprecatedAbstractAdminConstructorArgs
2614
     *
2615
     * @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.
2616
     */
2617
    public function testDeprecatedAbstractAdminConstructorArgs($code, $class, $baseControllerName): void
2618
    {
2619
        new PostAdmin($code, $class, $baseControllerName);
2620
    }
2621
2622
    public function getDeprecatedAbstractAdminConstructorArgs(): iterable
2623
    {
2624
        yield from [
2625
            ['sonata.post.admin.post', null, null],
2626
            [null, null, null],
2627
            ['sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', false],
2628
            ['sonata.post.admin.post', false, false],
2629
            [false, false, false],
2630
            [true, true, true],
2631
            [new \stdClass(), new \stdClass(), new \stdClass()],
2632
            [0, 0, 0],
2633
            [1, 1, 1],
2634
        ];
2635
    }
2636
}
2637