Completed
Pull Request — 3.x (#6263)
by
unknown
53:39
created

AdminTest::testGetModelManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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