Completed
Pull Request — 3.x (#6007)
by
unknown
04:33
created

AdminTest::testParent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
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\PostCategoryAdmin;
59
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostWithCustomRouteAdmin;
60
use Sonata\AdminBundle\Tests\Fixtures\Admin\TagAdmin;
61
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\BlogPost;
62
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment;
63
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Post;
64
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\PostCategory;
65
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Tag;
66
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
67
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToStringNull;
68
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
69
use Sonata\Doctrine\Adapter\AdapterInterface;
70
use Symfony\Component\DependencyInjection\Container;
71
use Symfony\Component\DependencyInjection\ContainerInterface;
72
use Symfony\Component\Filesystem\Filesystem;
73
use Symfony\Component\Form\FormBuilder;
74
use Symfony\Component\Form\FormBuilderInterface;
75
use Symfony\Component\Form\FormEvent;
76
use Symfony\Component\Form\FormEvents;
77
use Symfony\Component\Form\FormFactory;
78
use Symfony\Component\Form\FormRegistry;
79
use Symfony\Component\Form\ResolvedFormTypeFactory;
80
use Symfony\Component\HttpFoundation\ParameterBag;
81
use Symfony\Component\HttpFoundation\Request;
82
use Symfony\Component\PropertyAccess\PropertyAccess;
83
use Symfony\Component\Routing\RouterInterface;
84
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
85
use Symfony\Component\Translation\TranslatorInterface;
86
use Symfony\Component\Validator\Mapping\MemberMetadata;
87
use Symfony\Component\Validator\Mapping\PropertyMetadataInterface;
88
use Symfony\Component\Validator\Validator\ValidatorInterface;
89
90
class AdminTest extends TestCase
91
{
92
    protected $cacheTempFolder;
93
94
    protected function setUp(): void
95
    {
96
        $this->cacheTempFolder = sprintf('%s/sonata_test_route', sys_get_temp_dir());
97
        $filesystem = new Filesystem();
98
        $filesystem->remove($this->cacheTempFolder);
99
    }
100
101
    /**
102
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::__construct
103
     */
104
    public function testConstructor(): void
105
    {
106
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
107
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
108
109
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
110
        $this->assertInstanceOf(AbstractAdmin::class, $admin);
111
        $this->assertSame($class, $admin->getClass());
112
        $this->assertSame($baseControllerName, $admin->getBaseControllerName());
113
    }
114
115
    public function testGetClass(): void
116
    {
117
        $class = Post::class;
118
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
119
120
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
121
122
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
123
124
        $admin->setSubject(new BlogPost());
125
        $this->assertSame(BlogPost::class, $admin->getClass());
126
127
        $admin->setSubClasses(['foo']);
128
        $this->assertSame(BlogPost::class, $admin->getClass());
129
130
        $admin->setSubject(null);
131
        $admin->setSubClasses([]);
132
        $this->assertSame($class, $admin->getClass());
133
134
        $admin->setSubClasses(['foo' => 'bar']);
135
        $admin->setRequest(new Request(['subclass' => 'foo']));
136
        $this->assertSame('bar', $admin->getClass());
137
    }
138
139
    public function testGetClassException(): void
140
    {
141
        $this->expectException(\RuntimeException::class);
142
        $this->expectExceptionMessage('Feature not implemented: an embedded admin cannot have subclass');
143
144
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
145
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
146
147
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
148
        $admin->setParentFieldDescription(new FieldDescription());
149
        $admin->setSubClasses(['foo' => 'bar']);
150
        $admin->setRequest(new Request(['subclass' => 'foo']));
151
        $admin->getClass();
152
    }
153
154
    public function testCheckAccessThrowsExceptionOnMadeUpAction(): void
155
    {
156
        $admin = new PostAdmin(
157
            'sonata.post.admin.post',
158
            'Application\Sonata\NewsBundle\Entity\Post',
159
            'Sonata\NewsBundle\Controller\PostAdminController'
160
        );
161
        $this->expectException(
162
            \InvalidArgumentException::class
163
        );
164
        $this->expectExceptionMessage(
165
            'Action "made-up" could not be found'
166
        );
167
        $admin->checkAccess('made-up');
168
    }
169
170
    public function testCheckAccessThrowsAccessDeniedException(): void
171
    {
172
        $admin = new PostAdmin(
173
            'sonata.post.admin.post',
174
            'Application\Sonata\NewsBundle\Entity\Post',
175
            'Sonata\NewsBundle\Controller\PostAdminController'
176
        );
177
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
178
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
179
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
180
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
181
        $customExtension->getAccessMapping($admin)->willReturn(
182
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
183
        );
184
        $admin->addExtension($customExtension->reveal());
185
        $admin->setSecurityHandler($securityHandler->reveal());
186
        $this->expectException(
187
            AccessDeniedException::class
188
        );
189
        $this->expectExceptionMessage(
190
            'Access Denied to the action custom_action and role EXTRA_CUSTOM_ROLE'
191
        );
192
        $admin->checkAccess('custom_action');
193
    }
194
195
    public function testHasAccessOnMadeUpAction(): void
196
    {
197
        $admin = new PostAdmin(
198
            'sonata.post.admin.post',
199
            'Application\Sonata\NewsBundle\Entity\Post',
200
            'Sonata\NewsBundle\Controller\PostAdminController'
201
        );
202
203
        $this->assertFalse($admin->hasAccess('made-up'));
204
    }
205
206
    public function testHasAccess(): void
207
    {
208
        $admin = new PostAdmin(
209
            'sonata.post.admin.post',
210
            'Application\Sonata\NewsBundle\Entity\Post',
211
            'Sonata\NewsBundle\Controller\PostAdminController'
212
        );
213
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
214
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
215
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
216
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
217
        $customExtension->getAccessMapping($admin)->willReturn(
218
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
219
        );
220
        $admin->addExtension($customExtension->reveal());
221
        $admin->setSecurityHandler($securityHandler->reveal());
222
223
        $this->assertFalse($admin->hasAccess('custom_action'));
224
    }
225
226
    public function testHasAccessAllowsAccess(): void
227
    {
228
        $admin = new PostAdmin(
229
            'sonata.post.admin.post',
230
            'Application\Sonata\NewsBundle\Entity\Post',
231
            'Sonata\NewsBundle\Controller\PostAdminController'
232
        );
233
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
234
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
235
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(true);
236
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
237
        $customExtension->getAccessMapping($admin)->willReturn(
238
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
239
        );
240
        $admin->addExtension($customExtension->reveal());
241
        $admin->setSecurityHandler($securityHandler->reveal());
242
243
        $this->assertTrue($admin->hasAccess('custom_action'));
244
    }
245
246
    public function testHasAccessAllowsAccessEditAction(): void
247
    {
248
        $admin = new PostAdmin(
249
            'sonata.post.admin.post',
250
            'Application\Sonata\NewsBundle\Entity\Post',
251
            'Sonata\NewsBundle\Controller\PostAdminController'
252
        );
253
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
254
        $securityHandler->isGranted($admin, 'EDIT_ROLE', $admin)->willReturn(true);
255
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
256
        $customExtension->getAccessMapping($admin)->willReturn(
257
            ['edit_action' => ['EDIT_ROLE']]
258
        );
259
        $admin->addExtension($customExtension->reveal());
260
        $admin->setSecurityHandler($securityHandler->reveal());
261
262
        $this->assertTrue($admin->hasAccess('edit_action'));
263
    }
264
265
    /**
266
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChild
267
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::addChild
268
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChild
269
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::isChild
270
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChildren
271
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChildren
272
     */
273
    public function testChildren(): void
274
    {
275
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
276
        $this->assertFalse($postAdmin->hasChildren());
277
        $this->assertFalse($postAdmin->hasChild('comment'));
278
279
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
280
        $postAdmin->addChild($commentAdmin, 'post');
281
282
        $this->assertTrue($postAdmin->hasChildren());
283
        $this->assertTrue($postAdmin->hasChild('sonata.post.admin.comment'));
284
285
        $this->assertSame('sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getCode());
286
        $this->assertSame('sonata.post.admin.post|sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getBaseCodeRoute());
287
        $this->assertSame($postAdmin, $postAdmin->getChild('sonata.post.admin.comment')->getParent());
288
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
289
290
        $this->assertFalse($postAdmin->isChild());
291
        $this->assertTrue($commentAdmin->isChild());
292
293
        $this->assertSame(['sonata.post.admin.comment' => $commentAdmin], $postAdmin->getChildren());
294
    }
295
296
    /**
297
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getParent
298
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setParent
299
     */
300
    public function testParent(): void
301
    {
302
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
303
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
304
        $this->assertFalse($commentAdmin->isChild());
305
        $this->assertFalse($commentAdmin->hasParentFieldDescription());
306
307
        $commentAdmin->setParent($postAdmin, 'post');
308
309
        $this->assertSame($postAdmin, $commentAdmin->getParent());
310
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
311
    }
312
313
    /**
314
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configure
315
     */
316
    public function testConfigure(): void
317
    {
318
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
319
        $this->assertNotNull($admin->getUniqid());
320
321
        $admin->initialize();
322
        $this->assertNotNull($admin->getUniqid());
323
        $this->assertSame('Post', $admin->getClassnameLabel());
324
325
        $admin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
326
        $admin->setClassnameLabel('postcomment');
327
328
        $admin->initialize();
329
        $this->assertSame('postcomment', $admin->getClassnameLabel());
330
    }
331
332
    public function testConfigureWithValidParentAssociationMapping(): void
333
    {
334
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
335
        $admin->setParentAssociationMapping('Category');
336
337
        $admin->initialize();
338
        $this->assertSame('Category', $admin->getParentAssociationMapping());
339
    }
340
341
    public function provideGetBaseRoutePattern()
342
    {
343
        return [
344
            [
345
                'Application\Sonata\NewsBundle\Entity\Post',
346
                '/sonata/news/post',
347
            ],
348
            [
349
                'Application\Sonata\NewsBundle\Document\Post',
350
                '/sonata/news/post',
351
            ],
352
            [
353
                'MyApplication\MyBundle\Entity\Post',
354
                '/myapplication/my/post',
355
            ],
356
            [
357
                'MyApplication\MyBundle\Entity\Post\Category',
358
                '/myapplication/my/post-category',
359
            ],
360
            [
361
                'MyApplication\MyBundle\Entity\Product\Category',
362
                '/myapplication/my/product-category',
363
            ],
364
            [
365
                'MyApplication\MyBundle\Entity\Other\Product\Category',
366
                '/myapplication/my/other-product-category',
367
            ],
368
            [
369
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
370
                '/cmf/foo/menu',
371
            ],
372
            [
373
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
374
                '/cmf/foo/menu',
375
            ],
376
            [
377
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
378
                '/symfony/barbar/menu',
379
            ],
380
            [
381
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
382
                '/symfony/barbar/menu-item',
383
            ],
384
            [
385
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
386
                '/cmf/foo/menu',
387
            ],
388
            [
389
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
390
                '/cmf/foo/menu',
391
            ],
392
            [
393
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
394
                '/cmf/foo/menu',
395
            ],
396
            [
397
                'AppBundle\Entity\User',
398
                '/app/user',
399
            ],
400
            [
401
                'App\Entity\User',
402
                '/app/user',
403
            ],
404
        ];
405
    }
406
407
    /**
408
     * @dataProvider provideGetBaseRoutePattern
409
     */
410
    public function testGetBaseRoutePattern(string $objFqn, string $expected): void
411
    {
412
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
413
        $this->assertSame($expected, $admin->getBaseRoutePattern());
414
    }
415
416
    /**
417
     * @dataProvider provideGetBaseRoutePattern
418
     */
419
    public function testGetBaseRoutePatternWithChildAdmin(string $objFqn, string $expected): void
420
    {
421
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
422
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
423
        $commentAdmin->setParent($postAdmin, 'post');
424
425
        $this->assertSame(sprintf('%s/{id}/comment', $expected), $commentAdmin->getBaseRoutePattern());
426
    }
427
428
    /**
429
     * @dataProvider provideGetBaseRoutePattern
430
     */
431
    public function testGetBaseRoutePatternWithTwoNestedChildAdmin(string $objFqn, string $expected): void
432
    {
433
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
434
        $commentAdmin = new CommentAdmin(
435
            'sonata.post.admin.comment',
436
            'Application\Sonata\NewsBundle\Entity\Comment',
437
            'Sonata\NewsBundle\Controller\CommentAdminController'
438
        );
439
        $commentVoteAdmin = new CommentVoteAdmin(
440
            'sonata.post.admin.comment_vote',
441
            'Application\Sonata\NewsBundle\Entity\CommentVote',
442
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
443
        );
444
        $commentAdmin->setParent($postAdmin, 'post');
445
        $commentVoteAdmin->setParent($commentAdmin, 'comment');
446
447
        $this->assertSame(sprintf('%s/{id}/comment/{childId}/commentvote', $expected), $commentVoteAdmin->getBaseRoutePattern());
448
    }
449
450
    public function testGetBaseRoutePatternWithSpecifedPattern(): void
451
    {
452
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostWithCustomRouteAdminController');
453
454
        $this->assertSame('/post-custom', $postAdmin->getBaseRoutePattern());
455
    }
456
457
    public function testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern(): void
458
    {
459
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
460
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
461
        $commentAdmin->setParent($postAdmin, 'post');
462
463
        $this->assertSame('/sonata/news/post/{id}/comment-custom', $commentAdmin->getBaseRoutePattern());
464
    }
465
466
    public function testGetBaseRoutePatternWithUnreconizedClassname(): void
467
    {
468
        $this->expectException(\RuntimeException::class);
469
470
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
471
        $admin->getBaseRoutePattern();
472
    }
473
474
    public function provideGetBaseRouteName()
475
    {
476
        return [
477
            [
478
                'Application\Sonata\NewsBundle\Entity\Post',
479
                'admin_sonata_news_post',
480
            ],
481
            [
482
                'Application\Sonata\NewsBundle\Document\Post',
483
                'admin_sonata_news_post',
484
            ],
485
            [
486
                'MyApplication\MyBundle\Entity\Post',
487
                'admin_myapplication_my_post',
488
            ],
489
            [
490
                'MyApplication\MyBundle\Entity\Post\Category',
491
                'admin_myapplication_my_post_category',
492
            ],
493
            [
494
                'MyApplication\MyBundle\Entity\Product\Category',
495
                'admin_myapplication_my_product_category',
496
            ],
497
            [
498
                'MyApplication\MyBundle\Entity\Other\Product\Category',
499
                'admin_myapplication_my_other_product_category',
500
            ],
501
            [
502
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
503
                'admin_cmf_foo_menu',
504
            ],
505
            [
506
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
507
                'admin_cmf_foo_menu',
508
            ],
509
            [
510
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
511
                'admin_symfony_barbar_menu',
512
            ],
513
            [
514
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
515
                'admin_symfony_barbar_menu_item',
516
            ],
517
            [
518
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
519
                'admin_cmf_foo_menu',
520
            ],
521
            [
522
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
523
                'admin_cmf_foo_menu',
524
            ],
525
            [
526
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
527
                'admin_cmf_foo_menu',
528
            ],
529
            [
530
                'AppBundle\Entity\User',
531
                'admin_app_user',
532
            ],
533
            [
534
                'App\Entity\User',
535
                'admin_app_user',
536
            ],
537
        ];
538
    }
539
540
    /**
541
     * @dataProvider provideGetBaseRouteName
542
     */
543
    public function testGetBaseRouteName(string $objFqn, string $expected): void
544
    {
545
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
546
547
        $this->assertSame($expected, $admin->getBaseRouteName());
548
    }
549
550
    /**
551
     * @group legacy
552
     * @expectedDeprecation Calling "addChild" without second argument is deprecated since sonata-project/admin-bundle 3.35 and will not be allowed in 4.0.
553
     * @dataProvider provideGetBaseRouteName
554
     */
555
    public function testGetBaseRouteNameWithChildAdmin(string $objFqn, string $expected): void
556
    {
557
        $routeGenerator = new DefaultRouteGenerator(
558
            $this->createMock(RouterInterface::class),
559
            new RoutesCache($this->cacheTempFolder, true)
560
        );
561
562
        $container = new Container();
563
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
564
565
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
566
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
567
        $container->set('sonata.post.admin.post', $postAdmin);
568
        $postAdmin->setConfigurationPool($pool);
569
        $postAdmin->setRouteBuilder($pathInfo);
570
        $postAdmin->setRouteGenerator($routeGenerator);
571
        $postAdmin->initialize();
572
573
        $commentAdmin = new CommentAdmin(
574
            'sonata.post.admin.comment',
575
            'Application\Sonata\NewsBundle\Entity\Comment',
576
            'Sonata\NewsBundle\Controller\CommentAdminController'
577
        );
578
        $container->set('sonata.post.admin.comment', $commentAdmin);
579
        $commentAdmin->setConfigurationPool($pool);
580
        $commentAdmin->setRouteBuilder($pathInfo);
581
        $commentAdmin->setRouteGenerator($routeGenerator);
582
        $commentAdmin->initialize();
583
584
        $postAdmin->addChild($commentAdmin, 'post');
585
586
        $commentVoteAdmin = new CommentVoteAdmin(
587
            'sonata.post.admin.comment_vote',
588
            'Application\Sonata\NewsBundle\Entity\CommentVote',
589
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
590
        );
591
592
        $container->set('sonata.post.admin.comment_vote', $commentVoteAdmin);
593
        $commentVoteAdmin->setConfigurationPool($pool);
594
        $commentVoteAdmin->setRouteBuilder($pathInfo);
595
        $commentVoteAdmin->setRouteGenerator($routeGenerator);
596
        $commentVoteAdmin->initialize();
597
598
        $commentAdmin->addChild($commentVoteAdmin);
599
        $pool->setAdminServiceIds([
600
            'sonata.post.admin.post',
601
            'sonata.post.admin.comment',
602
            'sonata.post.admin.comment_vote',
603
        ]);
604
605
        $this->assertSame(sprintf('%s_comment', $expected), $commentAdmin->getBaseRouteName());
606
607
        $this->assertTrue($postAdmin->hasRoute('show'));
608
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
609
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.show'));
610
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment|sonata.post.admin.comment_vote.show'));
611
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment.list'));
612
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment|sonata.post.admin.comment_vote.list'));
613
        $this->assertFalse($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.edit'));
614
        $this->assertFalse($commentAdmin->hasRoute('edit'));
615
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
616
617
        /*
618
         * Test the route name from request
619
         */
620
        $postListRequest = new Request(
621
            [],
622
            [],
623
            [
624
                '_route' => sprintf('%s_list', $postAdmin->getBaseRouteName()),
625
            ]
626
        );
627
628
        $postAdmin->setRequest($postListRequest);
629
        $commentAdmin->setRequest($postListRequest);
630
631
        $this->assertTrue($postAdmin->isCurrentRoute('list'));
632
        $this->assertFalse($postAdmin->isCurrentRoute('create'));
633
        $this->assertFalse($commentAdmin->isCurrentRoute('list'));
634
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('list'));
635
        $this->assertTrue($commentAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
636
        $this->assertFalse($commentAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
637
        $this->assertTrue($commentVoteAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
638
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
639
    }
640
641
    public function testGetBaseRouteNameWithUnreconizedClassname(): void
642
    {
643
        $this->expectException(\RuntimeException::class);
644
645
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
646
        $admin->getBaseRouteName();
647
    }
648
649
    public function testGetBaseRouteNameWithSpecifiedName(): void
650
    {
651
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
652
653
        $this->assertSame('post_custom', $postAdmin->getBaseRouteName());
654
    }
655
656
    public function testGetBaseRouteNameWithChildAdminAndWithSpecifiedName(): void
657
    {
658
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
659
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
660
        $commentAdmin->setParent($postAdmin, 'post');
661
662
        $this->assertSame('admin_sonata_news_post_comment_custom', $commentAdmin->getBaseRouteName());
663
    }
664
665
    public function testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName(): void
666
    {
667
        $postAdmin = new PostAdmin(
668
            'sonata.post.admin.post',
669
            'Application\Sonata\NewsBundle\Entity\Post',
670
            'Sonata\NewsBundle\Controller\PostAdminController'
671
        );
672
        $commentAdmin = new CommentWithCustomRouteAdmin(
673
            'sonata.post.admin.comment_with_custom_route',
674
            'Application\Sonata\NewsBundle\Entity\Comment',
675
            'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController'
676
        );
677
        $commentVoteAdmin = new CommentVoteAdmin(
678
            'sonata.post.admin.comment_vote',
679
            'Application\Sonata\NewsBundle\Entity\CommentVote',
680
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
681
        );
682
        $commentAdmin->setParent($postAdmin, 'post');
683
        $commentVoteAdmin->setParent($commentAdmin, 'comment');
684
685
        $this->assertSame('admin_sonata_news_post_comment_custom_commentvote', $commentVoteAdmin->getBaseRouteName());
686
    }
687
688
    /**
689
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setUniqid
690
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getUniqid
691
     */
692
    public function testSetUniqid(): void
693
    {
694
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
695
696
        $uniqid = uniqid();
697
        $admin->setUniqid($uniqid);
698
699
        $this->assertSame($uniqid, $admin->getUniqid());
700
    }
701
702
    public function testToString(): void
703
    {
704
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
705
706
        $s = new \stdClass();
707
708
        $this->assertNotEmpty($admin->toString($s));
709
710
        $s = new FooToString();
711
        $this->assertSame('salut', $admin->toString($s));
712
713
        // To string method is implemented, but returns null
714
        $s = new FooToStringNull();
715
        $this->assertNotEmpty($admin->toString($s));
716
717
        $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...
718
    }
719
720
    public function testIsAclEnabled(): void
721
    {
722
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
723
724
        $this->assertFalse($postAdmin->isAclEnabled());
725
726
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
727
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
728
        $this->assertTrue($commentAdmin->isAclEnabled());
729
    }
730
731
    /**
732
     * @group legacy
733
     *
734
     * @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.
735
     *
736
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
737
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
738
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
739
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
740
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
741
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
742
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
743
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
744
     */
745
    public function testSubClass(): void
746
    {
747
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
748
        $admin = new PostAdmin(
749
            'sonata.post.admin.post',
750
            Post::class,
751
            'Sonata\NewsBundle\Controller\PostAdminController'
752
        );
753
        $this->assertFalse($admin->hasSubClass('test'));
754
        $this->assertFalse($admin->hasActiveSubClass());
755
        $this->assertCount(0, $admin->getSubClasses());
756
        $this->assertNull($admin->getActiveSubClass());
757
        $this->assertNull($admin->getActiveSubclassCode());
758
        $this->assertSame(Post::class, $admin->getClass());
759
760
        // Just for the record, if there is no inheritance set, the getSubject is not used
761
        // the getSubject can also lead to some issue
762
        $admin->setSubject(new BlogPost());
763
        $this->assertSame(BlogPost::class, $admin->getClass());
764
765
        $admin->setSubClasses([
766
            'extended1' => 'NewsBundle\Entity\PostExtended1',
767
            'extended2' => 'NewsBundle\Entity\PostExtended2',
768
        ]);
769
        $this->assertFalse($admin->hasSubClass('test'));
770
        $this->assertTrue($admin->hasSubClass('extended1'));
771
        $this->assertFalse($admin->hasActiveSubClass());
772
        $this->assertCount(2, $admin->getSubClasses());
773
        // NEXT_MAJOR: remove the following 2 `assertNull()` assertions
774
        $this->assertNull($admin->getActiveSubClass());
775
        $this->assertNull($admin->getActiveSubclassCode());
776
        $this->assertSame(
777
            BlogPost::class,
778
            $admin->getClass(),
779
            'When there is no subclass in the query the class parameter should be returned'
780
        );
781
782
        $request = new Request(['subclass' => 'extended1']);
783
        $admin->setRequest($request);
784
        $this->assertFalse($admin->hasSubClass('test'));
785
        $this->assertTrue($admin->hasSubClass('extended1'));
786
        $this->assertTrue($admin->hasActiveSubClass());
787
        $this->assertCount(2, $admin->getSubClasses());
788
        $this->assertSame(
789
            'NewsBundle\Entity\PostExtended1',
790
            $admin->getActiveSubClass(),
791
            'It should return the curently active sub class.'
792
        );
793
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
794
        $this->assertSame(
795
            'NewsBundle\Entity\PostExtended1',
796
            $admin->getClass(),
797
            'getClass() should return the name of the sub class when passed through a request query parameter.'
798
        );
799
800
        $request->query->set('subclass', 'inject');
801
802
        $this->assertNull($admin->getActiveSubclassCode());
803
        // NEXT_MAJOR: remove the previous `assertNull()` assertion and uncomment the following lines
804
        // $this->expectException(\LogicException::class);
805
        // $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
806
    }
807
808
    /**
809
     * @group legacy
810
     *
811
     * @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.
812
     */
813
    public function testNonExistantSubclass(): void
814
    {
815
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
816
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
817
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
818
819
        $admin->setRequest(new Request(['subclass' => 'inject']));
820
821
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
822
823
        $this->assertTrue($admin->hasActiveSubClass());
824
825
        $this->expectException(\RuntimeException::class);
826
827
        $admin->getActiveSubClass();
828
    }
829
830
    /**
831
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
832
     */
833
    public function testOnlyOneSubclassNeededToBeActive(): void
834
    {
835
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
836
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
837
        $request = new Request(['subclass' => 'extended1']);
838
        $admin->setRequest($request);
839
        $this->assertTrue($admin->hasActiveSubClass());
840
    }
841
842
    /**
843
     * @group legacy
844
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since sonata-project/admin-bundle 3.30 and will be removed in 4.0.
845
     */
846
    public function testAddSubClassIsDeprecated(): void
847
    {
848
        $admin = new PostAdmin(
849
            'sonata.post.admin.post',
850
            Post::class,
851
            'Sonata\NewsBundle\Controller\PostAdminController'
852
        );
853
        $admin->addSubClass('whatever');
854
    }
855
856
    /**
857
     * @group legacy
858
     */
859
    public function testGetPerPageOptions(): void
860
    {
861
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
862
863
        $perPageOptions = $admin->getPerPageOptions();
864
865
        foreach ($perPageOptions as $perPage) {
866
            $this->assertSame(0, $perPage % 4);
867
        }
868
869
        $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...
870
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
871
    }
872
873
    public function testGetLabelTranslatorStrategy(): void
874
    {
875
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
876
877
        $this->assertNull($admin->getLabelTranslatorStrategy());
878
879
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
880
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
881
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
882
    }
883
884
    public function testGetRouteBuilder(): void
885
    {
886
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
887
888
        $this->assertNull($admin->getRouteBuilder());
889
890
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
891
        $admin->setRouteBuilder($routeBuilder);
892
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
893
    }
894
895
    public function testGetMenuFactory(): void
896
    {
897
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
898
899
        $this->assertNull($admin->getMenuFactory());
900
901
        $menuFactory = $this->createMock(FactoryInterface::class);
902
        $admin->setMenuFactory($menuFactory);
903
        $this->assertSame($menuFactory, $admin->getMenuFactory());
904
    }
905
906
    public function testGetExtensions(): void
907
    {
908
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
909
910
        $this->assertSame([], $admin->getExtensions());
911
912
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
913
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
914
915
        $admin->addExtension($adminExtension1);
916
        $admin->addExtension($adminExtension2);
917
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
918
    }
919
920
    public function testGetFilterTheme(): void
921
    {
922
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
923
924
        $this->assertSame([], $admin->getFilterTheme());
925
926
        $admin->setFilterTheme(['FooTheme']);
927
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
928
    }
929
930
    public function testGetFormTheme(): void
931
    {
932
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
933
934
        $this->assertSame([], $admin->getFormTheme());
935
936
        $admin->setFormTheme(['FooTheme']);
937
938
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
939
    }
940
941
    public function testGetValidator(): void
942
    {
943
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
944
945
        $this->assertNull($admin->getValidator());
946
947
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
948
949
        $admin->setValidator($validator);
950
        $this->assertSame($validator, $admin->getValidator());
951
    }
952
953
    public function testGetSecurityHandler(): void
954
    {
955
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
956
957
        $this->assertNull($admin->getSecurityHandler());
958
959
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
960
        $admin->setSecurityHandler($securityHandler);
961
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
962
    }
963
964
    public function testGetSecurityInformation(): void
965
    {
966
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
967
968
        $this->assertSame([], $admin->getSecurityInformation());
969
970
        $securityInformation = [
971
            'GUEST' => ['VIEW', 'LIST'],
972
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
973
        ];
974
975
        $admin->setSecurityInformation($securityInformation);
976
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
977
    }
978
979
    public function testGetManagerType(): void
980
    {
981
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
982
983
        $this->assertNull($admin->getManagerType());
984
985
        $admin->setManagerType('foo_orm');
986
        $this->assertSame('foo_orm', $admin->getManagerType());
987
    }
988
989
    public function testGetModelManager(): void
990
    {
991
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
992
993
        $this->assertNull($admin->getModelManager());
994
995
        $modelManager = $this->createMock(ModelManagerInterface::class);
996
997
        $admin->setModelManager($modelManager);
998
        $this->assertSame($modelManager, $admin->getModelManager());
999
    }
1000
1001
    /**
1002
     * NEXT_MAJOR: remove this method.
1003
     *
1004
     * @group legacy
1005
     */
1006
    public function testGetBaseCodeRoute(): void
1007
    {
1008
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1009
1010
        $this->assertSame('', $admin->getBaseCodeRoute());
1011
1012
        $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...
1013
        $this->assertSame('foo', $admin->getBaseCodeRoute());
1014
    }
1015
1016
    // NEXT_MAJOR: uncomment this method.
1017
    // public function testGetBaseCodeRoute()
1018
    // {
1019
    //     $postAdmin = new PostAdmin(
1020
    //         'sonata.post.admin.post',
1021
    //         'NewsBundle\Entity\Post',
1022
    //         'Sonata\NewsBundle\Controller\PostAdminController'
1023
    //     );
1024
    //     $commentAdmin = new CommentAdmin(
1025
    //         'sonata.post.admin.comment',
1026
    //         'Application\Sonata\NewsBundle\Entity\Comment',
1027
    //         'Sonata\NewsBundle\Controller\CommentAdminController'
1028
    //     );
1029
    //
1030
    //     $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
1031
    //
1032
    //     $postAdmin->addChild($commentAdmin);
1033
    //
1034
    //     $this->assertSame(
1035
    //         'sonata.post.admin.post|sonata.post.admin.comment',
1036
    //         $commentAdmin->getBaseCodeRoute()
1037
    //     );
1038
    // }
1039
1040
    public function testGetRouteGenerator(): void
1041
    {
1042
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1043
1044
        $this->assertNull($admin->getRouteGenerator());
1045
1046
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1047
1048
        $admin->setRouteGenerator($routeGenerator);
1049
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1050
    }
1051
1052
    public function testGetConfigurationPool(): void
1053
    {
1054
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1055
1056
        $this->assertNull($admin->getConfigurationPool());
1057
1058
        $pool = $this->getMockBuilder(Pool::class)
1059
            ->disableOriginalConstructor()
1060
            ->getMock();
1061
1062
        $admin->setConfigurationPool($pool);
1063
        $this->assertSame($pool, $admin->getConfigurationPool());
1064
    }
1065
1066
    public function testGetShowBuilder(): void
1067
    {
1068
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1069
1070
        $this->assertNull($admin->getShowBuilder());
1071
1072
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1073
1074
        $admin->setShowBuilder($showBuilder);
1075
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1076
    }
1077
1078
    public function testGetListBuilder(): void
1079
    {
1080
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1081
1082
        $this->assertNull($admin->getListBuilder());
1083
1084
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1085
1086
        $admin->setListBuilder($listBuilder);
1087
        $this->assertSame($listBuilder, $admin->getListBuilder());
1088
    }
1089
1090
    public function testGetDatagridBuilder(): void
1091
    {
1092
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1093
1094
        $this->assertNull($admin->getDatagridBuilder());
1095
1096
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1097
1098
        $admin->setDatagridBuilder($datagridBuilder);
1099
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1100
    }
1101
1102
    public function testGetFormContractor(): void
1103
    {
1104
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1105
1106
        $this->assertNull($admin->getFormContractor());
1107
1108
        $formContractor = $this->createMock(FormContractorInterface::class);
1109
1110
        $admin->setFormContractor($formContractor);
1111
        $this->assertSame($formContractor, $admin->getFormContractor());
1112
    }
1113
1114
    public function testGetRequest(): void
1115
    {
1116
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1117
1118
        $this->assertFalse($admin->hasRequest());
1119
1120
        $request = new Request();
1121
1122
        $admin->setRequest($request);
1123
        $this->assertSame($request, $admin->getRequest());
1124
        $this->assertTrue($admin->hasRequest());
1125
    }
1126
1127
    public function testGetRequestWithException(): void
1128
    {
1129
        $this->expectException(\RuntimeException::class);
1130
        $this->expectExceptionMessage('The Request object has not been set');
1131
1132
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1133
        $admin->getRequest();
1134
    }
1135
1136
    public function testGetTranslationDomain(): void
1137
    {
1138
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1139
1140
        $this->assertSame('messages', $admin->getTranslationDomain());
1141
1142
        $admin->setTranslationDomain('foo');
1143
        $this->assertSame('foo', $admin->getTranslationDomain());
1144
    }
1145
1146
    /**
1147
     * @group legacy
1148
     */
1149
    public function testGetTranslator(): void
1150
    {
1151
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1152
1153
        $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...
1154
1155
        $translator = $this->createMock(TranslatorInterface::class);
1156
1157
        $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...
1158
        $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...
1159
    }
1160
1161
    public function testGetShowGroups(): void
1162
    {
1163
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1164
1165
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1166
        $this->assertFalse($admin->getShowGroups('sonata_deprecation_mute'));
1167
1168
        $groups = ['foo', 'bar', 'baz'];
1169
1170
        $admin->setShowGroups($groups);
1171
        $this->assertSame($groups, $admin->getShowGroups());
1172
    }
1173
1174
    public function testGetFormGroups(): void
1175
    {
1176
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1177
1178
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1179
        $this->assertFalse($admin->getFormGroups('sonata_deprecation_mute'));
1180
1181
        $groups = ['foo', 'bar', 'baz'];
1182
1183
        $admin->setFormGroups($groups);
1184
        $this->assertSame($groups, $admin->getFormGroups());
1185
    }
1186
1187
    public function testGetMaxPageLinks(): void
1188
    {
1189
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1190
1191
        $this->assertSame(25, $admin->getMaxPageLinks());
1192
1193
        $admin->setMaxPageLinks(14);
1194
        $this->assertSame(14, $admin->getMaxPageLinks());
1195
    }
1196
1197
    /**
1198
     * @group legacy
1199
     */
1200
    public function testGetMaxPerPage(): void
1201
    {
1202
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1203
1204
        $this->assertSame(32, $admin->getMaxPerPage());
1205
1206
        $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...
1207
        $this->assertSame(94, $admin->getMaxPerPage());
1208
    }
1209
1210
    public function testGetLabel(): void
1211
    {
1212
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1213
1214
        $this->assertNull($admin->getLabel());
1215
1216
        $admin->setLabel('FooLabel');
1217
        $this->assertSame('FooLabel', $admin->getLabel());
1218
    }
1219
1220
    public function testGetBaseController(): void
1221
    {
1222
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1223
1224
        $this->assertSame('Sonata\NewsBundle\Controller\PostAdminController', $admin->getBaseControllerName());
1225
1226
        $admin->setBaseControllerName('Sonata\NewsBundle\Controller\FooAdminController');
1227
        $this->assertSame('Sonata\NewsBundle\Controller\FooAdminController', $admin->getBaseControllerName());
1228
    }
1229
1230
    public function testGetTemplates(): void
1231
    {
1232
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1233
1234
        $templates = [
1235
            'list' => '@FooAdmin/CRUD/list.html.twig',
1236
            'show' => '@FooAdmin/CRUD/show.html.twig',
1237
            'edit' => '@FooAdmin/CRUD/edit.html.twig',
1238
        ];
1239
1240
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1241
        $templateRegistry->getTemplates()->shouldBeCalled()->willReturn($templates);
1242
1243
        $admin->setTemplateRegistry($templateRegistry->reveal());
1244
1245
        $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...
1246
    }
1247
1248
    public function testGetTemplate1(): void
1249
    {
1250
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1251
1252
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1253
        $templateRegistry->getTemplate('edit')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/edit.html.twig');
1254
        $templateRegistry->getTemplate('show')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/show.html.twig');
1255
1256
        $admin->setTemplateRegistry($templateRegistry->reveal());
1257
1258
        $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...
1259
        $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...
1260
    }
1261
1262
    public function testGetIdParameter(): void
1263
    {
1264
        $postAdmin = new PostAdmin(
1265
            'sonata.post.admin.post',
1266
            'NewsBundle\Entity\Post',
1267
            'Sonata\NewsBundle\Controller\PostAdminController'
1268
        );
1269
1270
        $this->assertSame('id', $postAdmin->getIdParameter());
1271
        $this->assertFalse($postAdmin->isChild());
1272
1273
        $commentAdmin = new CommentAdmin(
1274
            'sonata.post.admin.comment',
1275
            'Application\Sonata\NewsBundle\Entity\Comment',
1276
            'Sonata\NewsBundle\Controller\CommentAdminController'
1277
        );
1278
        $commentAdmin->setParent($postAdmin, 'post');
1279
1280
        $this->assertTrue($commentAdmin->isChild());
1281
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1282
1283
        $commentVoteAdmin = new CommentVoteAdmin(
1284
            'sonata.post.admin.comment_vote',
1285
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1286
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
1287
        );
1288
        $commentVoteAdmin->setParent($commentAdmin, 'comment');
1289
1290
        $this->assertTrue($commentVoteAdmin->isChild());
1291
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1292
    }
1293
1294
    public function testGetExportFormats(): void
1295
    {
1296
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1297
1298
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1299
    }
1300
1301
    public function testGetUrlsafeIdentifier(): void
1302
    {
1303
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1304
1305
        $model = new \stdClass();
1306
1307
        $modelManager = $this->createMock(ModelManagerInterface::class);
1308
        $modelManager->expects($this->once())
1309
            ->method('getUrlSafeIdentifier')
1310
            ->with($this->equalTo($model))
1311
            ->willReturn('foo');
1312
        $admin->setModelManager($modelManager);
1313
1314
        $this->assertSame('foo', $admin->getUrlSafeIdentifier($model));
1315
    }
1316
1317
    public function testDeterminedPerPageValue(): void
1318
    {
1319
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1320
1321
        $this->assertFalse($admin->determinedPerPageValue('foo'));
1322
        $this->assertFalse($admin->determinedPerPageValue(123));
1323
        $this->assertTrue($admin->determinedPerPageValue(16));
1324
    }
1325
1326
    public function testIsGranted(): void
1327
    {
1328
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1329
        $modelManager = $this->createStub(ModelManagerInterface::class);
1330
        $modelManager
1331
            ->method('getNormalizedIdentifier')
1332
            ->willReturnCallback(static function (?object $model = null): ?string {
1333
                return $model ? $model->id : null;
1334
            });
1335
1336
        $admin->setModelManager($modelManager);
1337
1338
        $entity1 = new \stdClass();
1339
        $entity1->id = '1';
1340
1341
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1342
        $securityHandler
1343
            ->expects($this->exactly(6))
1344
            ->method('isGranted')
1345
            ->willReturnCallback(static function (
1346
                AdminInterface $adminIn,
1347
                string $attributes,
1348
                ?object $object = null
1349
            ) use (
1350
                $admin,
1351
                $entity1
1352
            ): bool {
1353
                return $admin === $adminIn && 'FOO' === $attributes &&
1354
                    ($object === $admin || $object === $entity1);
1355
            });
1356
1357
        $admin->setSecurityHandler($securityHandler);
1358
1359
        $this->assertTrue($admin->isGranted('FOO'));
1360
        $this->assertTrue($admin->isGranted('FOO'));
1361
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1362
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1363
        $this->assertFalse($admin->isGranted('BAR'));
1364
        $this->assertFalse($admin->isGranted('BAR'));
1365
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1366
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1367
1368
        $entity2 = new \stdClass();
1369
        $entity2->id = '2';
1370
1371
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1372
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1373
1374
        $entity3 = new \stdClass();
1375
        $entity3->id = '3';
1376
1377
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1378
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1379
    }
1380
1381
    public function testSupportsPreviewMode(): void
1382
    {
1383
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1384
1385
        $this->assertFalse($admin->supportsPreviewMode());
1386
    }
1387
1388
    public function testGetPermissionsShow(): void
1389
    {
1390
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1391
1392
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1393
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1394
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1395
    }
1396
1397
    public function testShowIn(): void
1398
    {
1399
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1400
1401
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1402
        $securityHandler
1403
            ->method('isGranted')
1404
            ->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...
1405
                return $admin === $adminIn && $attributes === ['LIST'];
1406
            });
1407
1408
        $admin->setSecurityHandler($securityHandler);
1409
1410
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1411
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1412
        $this->assertTrue($admin->showIn('foo'));
1413
    }
1414
1415
    public function testGetObjectIdentifier(): void
1416
    {
1417
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1418
1419
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1420
    }
1421
1422
    /**
1423
     * @group legacy
1424
     */
1425
    public function testTrans(): void
1426
    {
1427
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1428
        $admin->setTranslationDomain('fooMessageDomain');
1429
1430
        $translator = $this->createMock(TranslatorInterface::class);
1431
        $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...
1432
1433
        $translator->expects($this->once())
1434
            ->method('trans')
1435
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1436
            ->willReturn('fooTranslated');
1437
1438
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1439
    }
1440
1441
    /**
1442
     * @group legacy
1443
     */
1444
    public function testTransWithMessageDomain(): void
1445
    {
1446
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
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('trans')
1453
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1454
            ->willReturn('fooTranslated');
1455
1456
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1457
    }
1458
1459
    /**
1460
     * @group legacy
1461
     */
1462
    public function testTransChoice(): void
1463
    {
1464
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1465
        $admin->setTranslationDomain('fooMessageDomain');
1466
1467
        $translator = $this->createMock(TranslatorInterface::class);
1468
        $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...
1469
1470
        $translator->expects($this->once())
1471
            ->method('transChoice')
1472
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1473
            ->willReturn('fooTranslated');
1474
1475
        $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...
1476
    }
1477
1478
    /**
1479
     * @group legacy
1480
     */
1481
    public function testTransChoiceWithMessageDomain(): void
1482
    {
1483
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1484
1485
        $translator = $this->createMock(TranslatorInterface::class);
1486
        $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...
1487
1488
        $translator->expects($this->once())
1489
            ->method('transChoice')
1490
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1491
            ->willReturn('fooTranslated');
1492
1493
        $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...
1494
    }
1495
1496
    public function testSetFilterPersister(): void
1497
    {
1498
        $admin = new class('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController') extends PostAdmin {
1499
            public function persistFilters(): bool
1500
            {
1501
                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...
1502
            }
1503
        };
1504
1505
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1506
1507
        $admin->setFilterPersister($filterPersister);
1508
        $this->assertTrue($admin->persistFilters());
1509
    }
1510
1511
    public function testGetRootCode(): void
1512
    {
1513
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1514
1515
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1516
1517
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1518
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1519
        $parentFieldDescription->expects($this->once())
1520
            ->method('getAdmin')
1521
            ->willReturn($parentAdmin);
1522
1523
        $this->assertFalse($admin->hasParentFieldDescription());
1524
        $admin->setParentFieldDescription($parentFieldDescription);
1525
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1526
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1527
    }
1528
1529
    public function testGetRoot(): void
1530
    {
1531
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1532
1533
        $this->assertSame($admin, $admin->getRoot());
1534
1535
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1536
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1537
        $parentFieldDescription->expects($this->once())
1538
            ->method('getAdmin')
1539
            ->willReturn($parentAdmin);
1540
1541
        $this->assertFalse($admin->hasParentFieldDescription());
1542
        $admin->setParentFieldDescription($parentFieldDescription);
1543
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1544
        $this->assertSame($parentAdmin, $admin->getRoot());
1545
    }
1546
1547
    public function testGetExportFields(): void
1548
    {
1549
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1550
1551
        $modelManager = $this->createMock(ModelManagerInterface::class);
1552
        $modelManager->expects($this->once())
1553
            ->method('getExportFields')
1554
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1555
            ->willReturn(['foo', 'bar']);
1556
1557
        $admin->setModelManager($modelManager);
1558
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1559
    }
1560
1561
    public function testGetPersistentParametersWithNoExtension(): void
1562
    {
1563
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1564
1565
        $this->assertEmpty($admin->getPersistentParameters());
1566
    }
1567
1568
    public function testGetPersistentParametersWithInvalidExtension(): void
1569
    {
1570
        $this->expectException(\RuntimeException::class);
1571
1572
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1573
1574
        $extension = $this->createMock(AdminExtensionInterface::class);
1575
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn(null);
1576
1577
        $admin->addExtension($extension);
1578
1579
        $admin->getPersistentParameters();
1580
    }
1581
1582
    public function testGetPersistentParametersWithValidExtension(): void
1583
    {
1584
        $expected = [
1585
            'context' => 'foobar',
1586
        ];
1587
1588
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1589
1590
        $extension = $this->createMock(AdminExtensionInterface::class);
1591
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1592
1593
        $admin->addExtension($extension);
1594
1595
        $this->assertSame($expected, $admin->getPersistentParameters());
1596
    }
1597
1598
    public function testGetNewInstanceForChildAdminWithParentValue(): void
1599
    {
1600
        $post = new Post();
1601
1602
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1603
        $postAdmin->method('getObject')->willReturn($post);
1604
1605
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1606
        $formBuilder->method('getForm')->willReturn(null);
1607
1608
        $tag = new Tag();
1609
1610
        $modelManager = $this->createStub(ModelManagerInterface::class);
1611
        $modelManager->method('getModelInstance')->willReturn($tag);
1612
1613
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1614
        $tagAdmin->setModelManager($modelManager);
1615
        $tagAdmin->setParent($postAdmin, 'post');
1616
1617
        $request = $this->createStub(Request::class);
1618
        $tagAdmin->setRequest($request);
1619
1620
        $configurationPool = $this->getMockBuilder(Pool::class)
1621
            ->disableOriginalConstructor()
1622
            ->getMock();
1623
1624
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1625
1626
        $tagAdmin->setConfigurationPool($configurationPool);
1627
1628
        $tag = $tagAdmin->getNewInstance();
1629
1630
        $this->assertSame($post, $tag->getPost());
1631
    }
1632
1633
    public function testGetNewInstanceForChildAdminWithCollectionParentValue(): void
1634
    {
1635
        $post = new Post();
1636
1637
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1638
        $postAdmin->method('getObject')->willReturn($post);
1639
1640
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1641
        $formBuilder->method('getForm')->willReturn(null);
1642
1643
        $postCategory = new PostCategory();
1644
1645
        $modelManager = $this->createStub(ModelManagerInterface::class);
1646
        $modelManager->method('getModelInstance')->willReturn($postCategory);
1647
1648
        $postCategoryAdmin = new PostCategoryAdmin('admin.post_category', PostCategoryAdmin::class, 'MyBundle\MyController');
1649
        $postCategoryAdmin->setModelManager($modelManager);
1650
        $postCategoryAdmin->setParent($postAdmin, 'post');
1651
1652
        $request = $this->createStub(Request::class);
1653
        $postCategoryAdmin->setRequest($request);
1654
1655
        $configurationPool = $this->getMockBuilder(Pool::class)
1656
            ->disableOriginalConstructor()
1657
            ->getMock();
1658
1659
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1660
1661
        $postCategoryAdmin->setConfigurationPool($configurationPool);
1662
1663
        $postCategory = $postCategoryAdmin->getNewInstance();
1664
1665
        $this->assertInstanceOf(Collection::class, $postCategory->getPosts());
1666
        $this->assertCount(1, $postCategory->getPosts());
1667
        $this->assertContains($post, $postCategory->getPosts());
1668
    }
1669
1670
    public function testGetNewInstanceForEmbededAdminWithParentValue(): void
1671
    {
1672
        $post = new Post();
1673
1674
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1675
        $postAdmin->method('getObject')->willReturn($post);
1676
1677
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1678
        $formBuilder->method('getForm')->willReturn(null);
1679
1680
        $parentField = $this->createStub(FieldDescriptionInterface::class);
1681
        $parentField->method('getAdmin')->willReturn($postAdmin);
1682
        $parentField->method('getParentAssociationMappings')->willReturn([]);
1683
        $parentField->method('getAssociationMapping')->willReturn(['fieldName' => 'tag', 'mappedBy' => 'post']);
1684
1685
        $tag = new Tag();
1686
1687
        $modelManager = $this->createStub(ModelManagerInterface::class);
1688
        $modelManager->method('getModelInstance')->willReturn($tag);
1689
1690
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1691
        $tagAdmin->setModelManager($modelManager);
1692
        $tagAdmin->setParentFieldDescription($parentField);
1693
1694
        $request = $this->createStub(Request::class);
1695
        $tagAdmin->setRequest($request);
1696
1697
        $configurationPool = $this->getMockBuilder(Pool::class)
1698
            ->disableOriginalConstructor()
1699
            ->getMock();
1700
1701
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1702
1703
        $tagAdmin->setConfigurationPool($configurationPool);
1704
1705
        $tag = $tagAdmin->getNewInstance();
1706
1707
        $this->assertSame($post, $tag->getPost());
1708
    }
1709
1710
    public function testFormAddPostSubmitEventForPreValidation(): void
1711
    {
1712
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1713
        $object = new \stdClass();
1714
1715
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1716
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1717
1718
        $validator = $this->createMock(ValidatorInterface::class);
1719
        $validator
1720
                ->method('getMetadataFor')
1721
                ->willReturn($this->createMock(MemberMetadata::class));
1722
        $modelAdmin->setValidator($validator);
1723
1724
        $modelManager = $this->createMock(ModelManagerInterface::class);
1725
        $modelManager
1726
            ->method('getNewFieldDescriptionInstance')
1727
            ->willReturn(new FieldDescription());
1728
        $modelAdmin->setModelManager($modelManager);
1729
1730
        // a Admin class to test that preValidate is called
1731
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1732
        $testAdminPreValidate->expects($this->once())
1733
                ->method('preValidate')
1734
                ->with($this->identicalTo($object));
1735
1736
        $event = $this->createMock(FormEvent::class);
1737
        $event
1738
                ->method('getData')
1739
                ->willReturn($object);
1740
1741
        $formBuild = $this->createMock(FormBuilder::class);
1742
        $formBuild->expects($this->once())
1743
                ->method('addEventListener')
1744
                ->with(
1745
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1746
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1747
                        if (\is_callable($callback)) {
1748
                            $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...
1749
                            $closure($event);
1750
1751
                            return true;
1752
                        }
1753
1754
                        return false;
1755
                    }),
1756
                    $this->greaterThan(0)
1757
                );
1758
1759
        $formContractor = $this->createMock(FormContractorInterface::class);
1760
        $formContractor
1761
                ->method('getDefaultOptions')
1762
                ->willReturn([]);
1763
        $formContractor
1764
                ->method('getFormBuilder')
1765
                ->willReturn($formBuild);
1766
1767
        $modelAdmin->setFormContractor($formContractor);
1768
        $modelAdmin->setSubject($object);
1769
        $modelAdmin->defineFormBuilder($formBuild);
1770
        $modelAdmin->getForm();
1771
    }
1772
1773
    public function testCanAddInlineValidationOnlyForGenericMetadata(): void
1774
    {
1775
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1776
        $object = new \stdClass();
1777
1778
        $labelTranslatorStrategy = $this->createStub(LabelTranslatorStrategyInterface::class);
1779
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1780
1781
        $validator = $this->createStub(ValidatorInterface::class);
1782
        $metadata = $this->createStub(PropertyMetadataInterface::class);
1783
        $validator
1784
            ->method('getMetadataFor')
1785
            ->willReturn($metadata);
1786
        $modelAdmin->setValidator($validator);
1787
1788
        $modelManager = $this->createStub(ModelManagerInterface::class);
1789
        $modelManager
1790
            ->method('getNewFieldDescriptionInstance')
1791
            ->willReturn(new FieldDescription());
1792
        $modelAdmin->setModelManager($modelManager);
1793
1794
        $event = $this->createStub(FormEvent::class);
1795
        $event
1796
            ->method('getData')
1797
            ->willReturn($object);
1798
1799
        $formBuild = $this->createStub(FormBuilder::class);
1800
1801
        $formContractor = $this->createStub(FormContractorInterface::class);
1802
        $formContractor
1803
            ->method('getDefaultOptions')
1804
            ->willReturn([]);
1805
        $formContractor
1806
            ->method('getFormBuilder')
1807
            ->willReturn($formBuild);
1808
1809
        $modelAdmin->setFormContractor($formContractor);
1810
        $modelAdmin->setSubject($object);
1811
1812
        $this->expectException(\RuntimeException::class);
1813
        $this->expectExceptionMessage(
1814
            sprintf(
1815
                'Cannot add inline validator for stdClass because its metadata is an instance of %s instead of Symfony\Component\Validator\Mapping\GenericMetadata',
1816
                \get_class($metadata)
1817
            )
1818
        );
1819
1820
        $modelAdmin->defineFormBuilder($formBuild);
1821
    }
1822
1823
    public function testRemoveFieldFromFormGroup(): void
1824
    {
1825
        $formGroups = [
1826
            'foobar' => [
1827
                'fields' => [
1828
                    'foo' => 'foo',
1829
                    'bar' => 'bar',
1830
                ],
1831
            ],
1832
        ];
1833
1834
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1835
        $admin->setFormGroups($formGroups);
1836
1837
        $admin->removeFieldFromFormGroup('foo');
1838
        $this->assertSame($admin->getFormGroups(), [
1839
            'foobar' => [
1840
                'fields' => [
1841
                    'bar' => 'bar',
1842
                ],
1843
            ],
1844
        ]);
1845
1846
        $admin->removeFieldFromFormGroup('bar');
1847
        $this->assertSame($admin->getFormGroups(), []);
1848
    }
1849
1850
    public function testGetFilterParameters(): void
1851
    {
1852
        $authorId = uniqid();
1853
1854
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1855
1856
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1857
        $commentAdmin->setParent($postAdmin, 'post.author');
1858
1859
        $request = $this->createMock(Request::class);
1860
        $query = $this->createMock(ParameterBag::class);
1861
        $query
1862
            ->method('get')
1863
            ->willReturn([
1864
                'filter' => [
1865
                    '_page' => '1',
1866
                    '_per_page' => '32',
1867
                ],
1868
            ]);
1869
1870
        $request->query = $query;
1871
        $request
1872
            ->method('get')
1873
            ->willReturn($authorId);
1874
1875
        $commentAdmin->setRequest($request);
1876
1877
        $modelManager = $this->createMock(ModelManagerInterface::class);
1878
        $modelManager
1879
            ->method('getDefaultSortValues')
1880
            ->willReturn([]);
1881
1882
        $commentAdmin->setModelManager($modelManager);
1883
1884
        $parameters = $commentAdmin->getFilterParameters();
1885
1886
        $this->assertTrue(isset($parameters['post__author']));
1887
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1888
    }
1889
1890
    public function testGetFilterFieldDescription(): void
1891
    {
1892
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1893
1894
        $fooFieldDescription = new FieldDescription();
1895
        $barFieldDescription = new FieldDescription();
1896
        $bazFieldDescription = new FieldDescription();
1897
1898
        $modelManager = $this->createMock(ModelManagerInterface::class);
1899
        $modelManager->expects($this->exactly(3))
1900
            ->method('getNewFieldDescriptionInstance')
1901
            ->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...
1902
                switch ($name) {
1903
                    case 'foo':
1904
                        $fieldDescription = $fooFieldDescription;
1905
1906
                        break;
1907
1908
                    case 'bar':
1909
                        $fieldDescription = $barFieldDescription;
1910
1911
                        break;
1912
1913
                    case 'baz':
1914
                        $fieldDescription = $bazFieldDescription;
1915
1916
                        break;
1917
1918
                    default:
1919
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1920
                        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...
1921
                }
1922
1923
                $fieldDescription->setName($name);
1924
1925
                return $fieldDescription;
1926
            });
1927
1928
        $modelAdmin->setModelManager($modelManager);
1929
1930
        $pager = $this->createMock(PagerInterface::class);
1931
1932
        $datagrid = $this->createMock(DatagridInterface::class);
1933
        $datagrid->expects($this->once())
1934
            ->method('getPager')
1935
            ->willReturn($pager);
1936
1937
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1938
        $datagridBuilder->expects($this->once())
1939
            ->method('getBaseDatagrid')
1940
            ->with($this->identicalTo($modelAdmin), [])
1941
            ->willReturn($datagrid);
1942
1943
        $datagridBuilder->expects($this->exactly(3))
1944
            ->method('addFilter')
1945
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1946
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1947
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1948
            });
1949
1950
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1951
1952
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1953
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1954
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1955
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1956
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1957
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1958
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1959
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1960
    }
1961
1962
    public function testGetSubjectNoRequest(): void
1963
    {
1964
        $modelManager = $this->createMock(ModelManagerInterface::class);
1965
        $modelManager
1966
            ->expects($this->never())
1967
            ->method('find');
1968
1969
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1970
        $admin->setModelManager($modelManager);
1971
1972
        $this->assertFalse($admin->hasSubject());
1973
    }
1974
1975
    public function testGetSideMenu(): void
1976
    {
1977
        $item = $this->createMock(ItemInterface::class);
1978
        $item
1979
            ->expects($this->once())
1980
            ->method('setChildrenAttribute')
1981
            ->with('class', 'nav navbar-nav');
1982
        $item
1983
            ->expects($this->once())
1984
            ->method('setExtra')
1985
            ->with('translation_domain', 'foo_bar_baz');
1986
1987
        $menuFactory = $this->createMock(FactoryInterface::class);
1988
        $menuFactory
1989
            ->expects($this->once())
1990
            ->method('createItem')
1991
            ->willReturn($item);
1992
1993
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1994
        $modelAdmin->setMenuFactory($menuFactory);
1995
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1996
1997
        $modelAdmin->getSideMenu('foo');
1998
    }
1999
2000
    /**
2001
     * @return array
2002
     */
2003
    public function provideGetSubject()
2004
    {
2005
        return [
2006
            [23],
2007
            ['azerty'],
2008
            ['4f69bbb5f14a13347f000092'],
2009
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
2010
            [sprintf('123%smy_type', AdapterInterface::ID_SEPARATOR)], // composite keys are supported
2011
        ];
2012
    }
2013
2014
    /**
2015
     * @dataProvider provideGetSubject
2016
     */
2017
    public function testGetSubjectFailed($id): void
2018
    {
2019
        $modelManager = $this->createMock(ModelManagerInterface::class);
2020
        $modelManager
2021
            ->expects($this->once())
2022
            ->method('find')
2023
            ->with('NewsBundle\Entity\Post', $id)
2024
            ->willReturn(null); // entity not found
2025
2026
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2027
        $admin->setModelManager($modelManager);
2028
2029
        $admin->setRequest(new Request(['id' => $id]));
2030
        $this->assertFalse($admin->hasSubject());
2031
    }
2032
2033
    /**
2034
     * @dataProvider provideGetSubject
2035
     */
2036
    public function testGetSubject($id): void
2037
    {
2038
        $model = new Post();
2039
2040
        $modelManager = $this->createMock(ModelManagerInterface::class);
2041
        $modelManager
2042
            ->expects($this->once())
2043
            ->method('find')
2044
            ->with('NewsBundle\Entity\Post', $id)
2045
            ->willReturn($model);
2046
2047
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2048
        $admin->setModelManager($modelManager);
2049
2050
        $admin->setRequest(new Request(['id' => $id]));
2051
        $this->assertTrue($admin->hasSubject());
2052
        $this->assertSame($model, $admin->getSubject());
2053
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
2054
    }
2055
2056
    public function testGetSubjectWithParentDescription(): void
2057
    {
2058
        $adminId = 1;
2059
2060
        $comment = new Comment();
2061
2062
        $modelManager = $this->createMock(ModelManagerInterface::class);
2063
        $modelManager
2064
            ->method('find')
2065
            ->with('NewsBundle\Entity\Comment', $adminId)
2066
            ->willReturn($comment);
2067
2068
        $request = new Request(['id' => $adminId]);
2069
2070
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2071
        $postAdmin->setRequest($request);
2072
2073
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
2074
        $commentAdmin->setRequest($request);
2075
        $commentAdmin->setModelManager($modelManager);
2076
2077
        $this->assertTrue($commentAdmin->hasSubject());
2078
        $this->assertSame($comment, $commentAdmin->getSubject());
2079
2080
        $commentAdmin->setSubject(null);
2081
        $commentAdmin->setParentFieldDescription(new FieldDescription());
2082
2083
        $this->assertFalse($commentAdmin->hasSubject());
2084
    }
2085
2086
    /**
2087
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2088
     */
2089
    public function testGetActionButtonsList(): void
2090
    {
2091
        $expected = [
2092
            'create' => [
2093
                'template' => 'Foo.html.twig',
2094
            ],
2095
        ];
2096
2097
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2098
2099
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2100
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
2101
2102
        $admin->setTemplateRegistry($templateRegistry->reveal());
2103
2104
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2105
        $securityHandler
2106
            ->expects($this->once())
2107
            ->method('isGranted')
2108
            ->with($admin, 'CREATE', $admin)
2109
            ->willReturn(true);
2110
        $admin->setSecurityHandler($securityHandler);
2111
2112
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2113
        $routeGenerator
2114
            ->expects($this->once())
2115
            ->method('hasAdminRoute')
2116
            ->with($admin, 'create')
2117
            ->willReturn(true);
2118
        $admin->setRouteGenerator($routeGenerator);
2119
2120
        $this->assertSame($expected, $admin->getActionButtons('list', null));
2121
    }
2122
2123
    /**
2124
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2125
     */
2126
    public function testGetActionButtonsListCreateDisabled(): void
2127
    {
2128
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2129
2130
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2131
        $securityHandler
2132
            ->expects($this->once())
2133
            ->method('isGranted')
2134
            ->with($admin, 'CREATE', $admin)
2135
            ->willReturn(false);
2136
        $admin->setSecurityHandler($securityHandler);
2137
2138
        $this->assertSame([], $admin->getActionButtons('list', null));
2139
    }
2140
2141
    /**
2142
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
2143
     */
2144
    public function testGetBatchActions(): void
2145
    {
2146
        $expected = [
2147
            'delete' => [
2148
                'label' => 'action_delete',
2149
                'translation_domain' => 'SonataAdminBundle',
2150
                'ask_confirmation' => true, // by default always true
2151
            ],
2152
            'foo' => [
2153
                'label' => 'action_foo',
2154
                'translation_domain' => 'SonataAdminBundle',
2155
            ],
2156
            'bar' => [
2157
                'label' => 'batch.label_bar',
2158
                'translation_domain' => 'SonataAdminBundle',
2159
            ],
2160
            'baz' => [
2161
                'label' => 'action_baz',
2162
                'translation_domain' => 'AcmeAdminBundle',
2163
            ],
2164
        ];
2165
2166
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2167
2168
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
2169
        $labelTranslatorStrategy
2170
            ->method('getLabel')
2171
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2172
                return sprintf('%s.%s_%s', $context, $type, $label);
2173
            });
2174
2175
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2176
        $admin->setRouteBuilder($pathInfo);
2177
        $admin->setTranslationDomain('SonataAdminBundle');
2178
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
2179
2180
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2181
        $routeGenerator
2182
            ->expects($this->once())
2183
            ->method('hasAdminRoute')
2184
            ->with($admin, 'delete')
2185
            ->willReturn(true);
2186
        $admin->setRouteGenerator($routeGenerator);
2187
2188
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2189
        $securityHandler
2190
            ->method('isGranted')
2191
            ->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...
2192
                return $admin === $adminIn && 'DELETE' === $attributes;
2193
            });
2194
        $admin->setSecurityHandler($securityHandler);
2195
2196
        $this->assertSame($expected, $admin->getBatchActions());
2197
    }
2198
2199
    /**
2200
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2201
     */
2202
    public function testShowMosaicButton(): void
2203
    {
2204
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2205
        $listModes = $admin->getListModes();
2206
2207
        $admin->showMosaicButton(true);
2208
2209
        $this->assertSame($listModes, $admin->getListModes());
2210
    }
2211
2212
    /**
2213
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2214
     */
2215
    public function testShowMosaicButtonHideMosaic(): void
2216
    {
2217
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2218
        $listModes = $admin->getListModes();
2219
        $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...
2220
2221
        $admin->showMosaicButton(false);
2222
2223
        $this->assertSame($expected, $admin->getListModes());
2224
    }
2225
2226
    /**
2227
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2228
     * @dataProvider provideGetBaseRouteName
2229
     */
2230
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2231
    {
2232
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2233
2234
        $routeGenerator = new DefaultRouteGenerator(
2235
            $this->createMock(RouterInterface::class),
2236
            new RoutesCache($this->cacheTempFolder, true)
2237
        );
2238
2239
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
2240
        $admin->setRouteBuilder($pathInfo);
2241
        $admin->setRouteGenerator($routeGenerator);
2242
        $admin->initialize();
2243
2244
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2245
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2246
2247
        $admin->setTemplateRegistry($templateRegistry->reveal());
2248
2249
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2250
        $securityHandler
2251
            ->method('isGranted')
2252
            ->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...
2253
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2254
            });
2255
2256
        $admin->setSecurityHandler($securityHandler);
2257
2258
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2259
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2260
    }
2261
2262
    /**
2263
     * NEXT_MAJOR: Remove the assertion about isDefaultFilter method and the legacy group.
2264
     *
2265
     * @group legacy
2266
     *
2267
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::isDefaultFilter" is deprecated since sonata-project/admin-bundle 3.x.
2268
     */
2269
    public function testDefaultFilters(): void
2270
    {
2271
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2272
2273
        $subjectId = uniqid();
2274
2275
        $request = $this->createMock(Request::class);
2276
        $query = $this->createMock(ParameterBag::class);
2277
        $query
2278
            ->method('get')
2279
            ->with($this->equalTo('filter'))
2280
            ->willReturn([
2281
                'a' => [
2282
                    'value' => 'b',
2283
                ],
2284
                'foo' => [
2285
                    'type' => '1',
2286
                    'value' => 'bar',
2287
                ],
2288
                'baz' => [
2289
                    'type' => '5',
2290
                    'value' => 'test',
2291
                ],
2292
            ]);
2293
        $request->query = $query;
2294
2295
        $request
2296
            ->method('get')
2297
            ->willReturn($subjectId);
2298
2299
        $admin->setRequest($request);
2300
2301
        $modelManager = $this->createMock(ModelManagerInterface::class);
2302
        $modelManager
2303
            ->method('getDefaultSortValues')
2304
            ->willReturn([]);
2305
2306
        $admin->setModelManager($modelManager);
2307
2308
        $this->assertSame([
2309
            '_page' => 1,
2310
            '_per_page' => 32,
2311
            'foo' => [
2312
                'type' => '1',
2313
                'value' => 'bar',
2314
            ],
2315
            'baz' => [
2316
                'type' => '5',
2317
                'value' => 'test',
2318
            ],
2319
            'a' => [
2320
                'value' => 'b',
2321
            ],
2322
        ], $admin->getFilterParameters());
2323
2324
        $this->assertTrue($admin->isDefaultFilter('foo'));
2325
        $this->assertFalse($admin->isDefaultFilter('bar'));
2326
        $this->assertFalse($admin->isDefaultFilter('a'));
2327
    }
2328
2329
    /**
2330
     * @group legacy
2331
     */
2332
    public function testDefaultBreadcrumbsBuilder(): void
2333
    {
2334
        $container = $this->createMock(ContainerInterface::class);
2335
        $container->expects($this->once())
2336
            ->method('getParameter')
2337
            ->with('sonata.admin.configuration.breadcrumbs')
2338
            ->willReturn([]);
2339
2340
        $pool = $this->getMockBuilder(Pool::class)
2341
            ->disableOriginalConstructor()
2342
            ->getMock();
2343
        $pool->expects($this->once())
2344
            ->method('getContainer')
2345
            ->willReturn($container);
2346
2347
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2348
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2349
        ], '', true, true, true, ['getConfigurationPool']);
2350
        $admin->expects($this->once())
2351
            ->method('getConfigurationPool')
2352
            ->willReturn($pool);
2353
2354
        $this->assertInstanceOf(BreadcrumbsBuilder::class, $admin->getBreadcrumbsBuilder());
2355
    }
2356
2357
    /**
2358
     * @group legacy
2359
     */
2360
    public function testBreadcrumbsBuilderSetter(): void
2361
    {
2362
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2363
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2364
        ]);
2365
        $this->assertSame($admin, $admin->setBreadcrumbsBuilder($builder = $this->createMock(
2366
            BreadcrumbsBuilderInterface::class
2367
        )));
2368
        $this->assertSame($builder, $admin->getBreadcrumbsBuilder());
2369
    }
2370
2371
    /**
2372
     * @group legacy
2373
     */
2374
    public function testGetBreadcrumbs(): void
2375
    {
2376
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2377
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2378
        ]);
2379
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2380
        $action = 'myaction';
2381
        $builder->getBreadcrumbs($admin, $action)->shouldBeCalled();
2382
        $admin->setBreadcrumbsBuilder($builder->reveal())->getBreadcrumbs($action);
2383
    }
2384
2385
    /**
2386
     * @group legacy
2387
     */
2388
    public function testBuildBreadcrumbs(): void
2389
    {
2390
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2391
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2392
        ]);
2393
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2394
        $action = 'myaction';
2395
        $menu = $this->createMock(ItemInterface::class);
2396
        $builder->buildBreadcrumbs($admin, $action, $menu)
2397
            ->shouldBeCalledTimes(1)
2398
            ->willReturn($menu);
2399
        $admin->setBreadcrumbsBuilder($builder->reveal());
2400
2401
        /* check the called is proxied only once */
2402
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2403
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2404
    }
2405
2406
    /**
2407
     * NEXT_MAJOR: remove this method.
2408
     *
2409
     * @group legacy
2410
     */
2411
    public function testCreateQueryLegacyCallWorks(): void
2412
    {
2413
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2414
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2415
        ]);
2416
        $query = $this->createMock(ProxyQueryInterface::class);
2417
        $modelManager = $this->createMock(ModelManagerInterface::class);
2418
        $modelManager->expects($this->once())
2419
            ->method('createQuery')
2420
            ->with('My\Class')
2421
            ->willReturn($query);
2422
2423
        $admin->setModelManager($modelManager);
2424
        $this->assertSame($query, $admin->createQuery('list'));
2425
    }
2426
2427
    public function testGetDataSourceIterator(): void
2428
    {
2429
        $datagrid = $this->createMock(DatagridInterface::class);
2430
        $datagrid->method('buildPager');
2431
2432
        $modelManager = $this->createMock(ModelManagerInterface::class);
2433
        $modelManager->method('getExportFields')->willReturn([
2434
            'field',
2435
            'foo',
2436
            'bar',
2437
        ]);
2438
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2439
            ->with($this->equalTo($datagrid), $this->equalTo([
2440
                'Feld' => 'field',
2441
                1 => 'foo',
2442
                2 => 'bar',
2443
            ]));
2444
2445
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2446
            ->disableOriginalConstructor()
2447
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2448
            ->getMockForAbstractClass();
2449
        $admin->method('getDatagrid')->willReturn($datagrid);
2450
        $admin->setModelManager($modelManager);
2451
2452
        $admin
2453
            ->method('getTranslationLabel')
2454
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2455
                return sprintf('%s.%s_%s', $context, $type, $label);
2456
            });
2457
        $admin
2458
            ->method('trans')
2459
            ->willReturnCallback(static function (string $label): string {
2460
                if ('export.label_field' === $label) {
2461
                    return 'Feld';
2462
                }
2463
2464
                return $label;
2465
            });
2466
2467
        $admin->getDataSourceIterator();
2468
    }
2469
2470
    public function testCircularChildAdmin(): void
2471
    {
2472
        $this->expectException(\RuntimeException::class);
2473
        $this->expectExceptionMessage(
2474
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2475
        );
2476
2477
        $postAdmin = new PostAdmin(
2478
            'sonata.post.admin.post',
2479
            'Application\Sonata\NewsBundle\Entity\Post',
2480
            'Sonata\NewsBundle\Controller\PostAdminController'
2481
        );
2482
        $commentAdmin = new CommentAdmin(
2483
            'sonata.post.admin.comment',
2484
            'Application\Sonata\NewsBundle\Entity\Comment',
2485
            'Sonata\NewsBundle\Controller\CommentAdminController'
2486
        );
2487
        $postAdmin->addChild($commentAdmin, 'post');
2488
        $commentAdmin->addChild($postAdmin, 'comment');
2489
    }
2490
2491
    public function testCircularChildAdminTripleLevel(): void
2492
    {
2493
        $this->expectException(\RuntimeException::class);
2494
        $this->expectExceptionMessage(
2495
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2496
        );
2497
2498
        $postAdmin = new PostAdmin(
2499
            'sonata.post.admin.post',
2500
            'Application\Sonata\NewsBundle\Entity\Post',
2501
            'Sonata\NewsBundle\Controller\PostAdminController'
2502
        );
2503
        $commentAdmin = new CommentAdmin(
2504
            'sonata.post.admin.comment',
2505
            'Application\Sonata\NewsBundle\Entity\Comment',
2506
            'Sonata\NewsBundle\Controller\CommentAdminController'
2507
        );
2508
        $commentVoteAdmin = new CommentVoteAdmin(
2509
            'sonata.post.admin.comment_vote',
2510
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2511
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2512
        );
2513
        $postAdmin->addChild($commentAdmin, 'post');
2514
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2515
        $commentVoteAdmin->addChild($postAdmin, 'post');
2516
    }
2517
2518
    public function testCircularChildAdminWithItself(): void
2519
    {
2520
        $this->expectException(\RuntimeException::class);
2521
        $this->expectExceptionMessage(
2522
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2523
        );
2524
2525
        $postAdmin = new PostAdmin(
2526
            'sonata.post.admin.post',
2527
            'Application\Sonata\NewsBundle\Entity\Post',
2528
            'Sonata\NewsBundle\Controller\PostAdminController'
2529
        );
2530
        $postAdmin->addChild($postAdmin);
2531
    }
2532
2533
    public function testGetRootAncestor(): void
2534
    {
2535
        $postAdmin = new PostAdmin(
2536
            'sonata.post.admin.post',
2537
            'Application\Sonata\NewsBundle\Entity\Post',
2538
            'Sonata\NewsBundle\Controller\PostAdminController'
2539
        );
2540
        $commentAdmin = new CommentAdmin(
2541
            'sonata.post.admin.comment',
2542
            'Application\Sonata\NewsBundle\Entity\Comment',
2543
            'Sonata\NewsBundle\Controller\CommentAdminController'
2544
        );
2545
        $commentVoteAdmin = new CommentVoteAdmin(
2546
            'sonata.post.admin.comment_vote',
2547
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2548
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2549
        );
2550
2551
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2552
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2553
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2554
2555
        $postAdmin->addChild($commentAdmin, 'post');
2556
2557
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2558
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2559
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2560
2561
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2562
2563
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2564
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2565
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2566
    }
2567
2568
    public function testGetChildDepth(): void
2569
    {
2570
        $postAdmin = new PostAdmin(
2571
            'sonata.post.admin.post',
2572
            'Application\Sonata\NewsBundle\Entity\Post',
2573
            'Sonata\NewsBundle\Controller\PostAdminController'
2574
        );
2575
        $commentAdmin = new CommentAdmin(
2576
            'sonata.post.admin.comment',
2577
            'Application\Sonata\NewsBundle\Entity\Comment',
2578
            'Sonata\NewsBundle\Controller\CommentAdminController'
2579
        );
2580
        $commentVoteAdmin = new CommentVoteAdmin(
2581
            'sonata.post.admin.comment_vote',
2582
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2583
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2584
        );
2585
2586
        $this->assertSame(0, $postAdmin->getChildDepth());
2587
        $this->assertSame(0, $commentAdmin->getChildDepth());
2588
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2589
2590
        $postAdmin->addChild($commentAdmin, 'post');
2591
2592
        $this->assertSame(0, $postAdmin->getChildDepth());
2593
        $this->assertSame(1, $commentAdmin->getChildDepth());
2594
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2595
2596
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2597
2598
        $this->assertSame(0, $postAdmin->getChildDepth());
2599
        $this->assertSame(1, $commentAdmin->getChildDepth());
2600
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2601
    }
2602
2603
    public function testGetCurrentLeafChildAdmin(): void
2604
    {
2605
        $postAdmin = new PostAdmin(
2606
            'sonata.post.admin.post',
2607
            'Application\Sonata\NewsBundle\Entity\Post',
2608
            'Sonata\NewsBundle\Controller\PostAdminController'
2609
        );
2610
        $commentAdmin = new CommentAdmin(
2611
            'sonata.post.admin.comment',
2612
            'Application\Sonata\NewsBundle\Entity\Comment',
2613
            'Sonata\NewsBundle\Controller\CommentAdminController'
2614
        );
2615
        $commentVoteAdmin = new CommentVoteAdmin(
2616
            'sonata.post.admin.comment_vote',
2617
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2618
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2619
        );
2620
2621
        $postAdmin->addChild($commentAdmin, 'post');
2622
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2623
2624
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2625
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2626
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2627
2628
        $commentAdmin->setCurrentChild(true);
2629
2630
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2631
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2632
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2633
2634
        $commentVoteAdmin->setCurrentChild(true);
2635
2636
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2637
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2638
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2639
    }
2640
2641
    public function testAdminWithoutControllerName(): void
2642
    {
2643
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', null);
2644
2645
        $this->assertNull($admin->getBaseControllerName());
2646
    }
2647
2648
    public function testAdminAvoidInifiniteLoop(): void
2649
    {
2650
        $this->expectNotToPerformAssertions();
2651
2652
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2653
2654
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2655
        $admin->setSubject(new \stdClass());
2656
2657
        $admin->setFormContractor(new FormContractor($formFactory));
2658
2659
        $admin->setShowBuilder(new ShowBuilder());
2660
2661
        $admin->setListBuilder(new ListBuilder());
2662
2663
        $pager = $this->createStub(PagerInterface::class);
2664
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2665
2666
        $validator = $this->createMock(ValidatorInterface::class);
2667
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2668
        $admin->setValidator($validator);
2669
2670
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2671
        $admin->setRouteGenerator($routeGenerator);
2672
2673
        $admin->getForm();
2674
        $admin->getShow();
2675
        $admin->getList();
2676
        $admin->getDatagrid();
2677
    }
2678
2679
    /**
2680
     * NEXT_MAJOR: Remove this test and its data provider.
2681
     *
2682
     * @group legacy
2683
     *
2684
     * @dataProvider getDeprecatedAbstractAdminConstructorArgs
2685
     *
2686
     * @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.
2687
     */
2688
    public function testDeprecatedAbstractAdminConstructorArgs($code, $class, $baseControllerName): void
2689
    {
2690
        new PostAdmin($code, $class, $baseControllerName);
2691
    }
2692
2693
    public function getDeprecatedAbstractAdminConstructorArgs(): iterable
2694
    {
2695
        yield from [
2696
            ['sonata.post.admin.post', null, null],
2697
            [null, null, null],
2698
            ['sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', false],
2699
            ['sonata.post.admin.post', false, false],
2700
            [false, false, false],
2701
            [true, true, true],
2702
            [new \stdClass(), new \stdClass(), new \stdClass()],
2703
            [0, 0, 0],
2704
            [1, 1, 1],
2705
        ];
2706
    }
2707
}
2708