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

AdminTest::testGetFormWithArrayParentValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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