Completed
Push — 3.x ( c2ec31...538660 )
by Christian
04:44
created

AdminTest::testAdminAvoidInifiniteLoop()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

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