Completed
Push — 3.x ( 3e834f...38b337 )
by Grégoire
03:36
created

testCanAddInlineValidationOnlyForGenericMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 49
rs 9.1127
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\Mapping\PropertyMetadataInterface;
86
use Symfony\Component\Validator\Validator\ValidatorInterface;
87
88
class AdminTest extends TestCase
89
{
90
    protected $cacheTempFolder;
91
92
    protected function setUp(): void
93
    {
94
        $this->cacheTempFolder = sys_get_temp_dir().'/sonata_test_route';
95
        $filesystem = new Filesystem();
96
        $filesystem->remove($this->cacheTempFolder);
97
    }
98
99
    /**
100
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::__construct
101
     */
102
    public function testConstructor(): void
103
    {
104
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
105
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
106
107
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
108
        $this->assertInstanceOf(AbstractAdmin::class, $admin);
109
        $this->assertSame($class, $admin->getClass());
110
        $this->assertSame($baseControllerName, $admin->getBaseControllerName());
111
    }
112
113
    public function testGetClass(): void
114
    {
115
        $class = Post::class;
116
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
117
118
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
119
120
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
121
122
        $admin->setSubject(new BlogPost());
123
        $this->assertSame(BlogPost::class, $admin->getClass());
124
125
        $admin->setSubClasses(['foo']);
126
        $this->assertSame(BlogPost::class, $admin->getClass());
127
128
        $admin->setSubject(null);
129
        $admin->setSubClasses([]);
130
        $this->assertSame($class, $admin->getClass());
131
132
        $admin->setSubClasses(['foo' => 'bar']);
133
        $admin->setRequest(new Request(['subclass' => 'foo']));
134
        $this->assertSame('bar', $admin->getClass());
135
    }
136
137
    public function testGetClassException(): void
138
    {
139
        $this->expectException(\RuntimeException::class);
140
        $this->expectExceptionMessage('Feature not implemented: an embedded admin cannot have subclass');
141
142
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
143
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
144
145
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
146
        $admin->setParentFieldDescription(new FieldDescription());
147
        $admin->setSubClasses(['foo' => 'bar']);
148
        $admin->setRequest(new Request(['subclass' => 'foo']));
149
        $admin->getClass();
150
    }
151
152
    public function testCheckAccessThrowsExceptionOnMadeUpAction(): void
153
    {
154
        $admin = new PostAdmin(
155
            'sonata.post.admin.post',
156
            'Application\Sonata\NewsBundle\Entity\Post',
157
            'Sonata\NewsBundle\Controller\PostAdminController'
158
        );
159
        $this->expectException(
160
            \InvalidArgumentException::class
161
        );
162
        $this->expectExceptionMessage(
163
            'Action "made-up" could not be found'
164
        );
165
        $admin->checkAccess('made-up');
166
    }
167
168
    public function testCheckAccessThrowsAccessDeniedException(): void
169
    {
170
        $admin = new PostAdmin(
171
            'sonata.post.admin.post',
172
            'Application\Sonata\NewsBundle\Entity\Post',
173
            'Sonata\NewsBundle\Controller\PostAdminController'
174
        );
175
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
176
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
177
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
178
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
179
        $customExtension->getAccessMapping($admin)->willReturn(
180
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
181
        );
182
        $admin->addExtension($customExtension->reveal());
183
        $admin->setSecurityHandler($securityHandler->reveal());
184
        $this->expectException(
185
            AccessDeniedException::class
186
        );
187
        $this->expectExceptionMessage(
188
            'Access Denied to the action custom_action and role EXTRA_CUSTOM_ROLE'
189
        );
190
        $admin->checkAccess('custom_action');
191
    }
192
193
    public function testHasAccessOnMadeUpAction(): void
194
    {
195
        $admin = new PostAdmin(
196
            'sonata.post.admin.post',
197
            'Application\Sonata\NewsBundle\Entity\Post',
198
            'Sonata\NewsBundle\Controller\PostAdminController'
199
        );
200
201
        $this->assertFalse($admin->hasAccess('made-up'));
202
    }
203
204
    public function testHasAccess(): void
205
    {
206
        $admin = new PostAdmin(
207
            'sonata.post.admin.post',
208
            'Application\Sonata\NewsBundle\Entity\Post',
209
            'Sonata\NewsBundle\Controller\PostAdminController'
210
        );
211
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
212
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
213
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
214
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
215
        $customExtension->getAccessMapping($admin)->willReturn(
216
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
217
        );
218
        $admin->addExtension($customExtension->reveal());
219
        $admin->setSecurityHandler($securityHandler->reveal());
220
221
        $this->assertFalse($admin->hasAccess('custom_action'));
222
    }
223
224
    public function testHasAccessAllowsAccess(): void
225
    {
226
        $admin = new PostAdmin(
227
            'sonata.post.admin.post',
228
            'Application\Sonata\NewsBundle\Entity\Post',
229
            'Sonata\NewsBundle\Controller\PostAdminController'
230
        );
231
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
232
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
233
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(true);
234
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
235
        $customExtension->getAccessMapping($admin)->willReturn(
236
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
237
        );
238
        $admin->addExtension($customExtension->reveal());
239
        $admin->setSecurityHandler($securityHandler->reveal());
240
241
        $this->assertTrue($admin->hasAccess('custom_action'));
242
    }
243
244
    public function testHasAccessAllowsAccessEditAction(): void
245
    {
246
        $admin = new PostAdmin(
247
            'sonata.post.admin.post',
248
            'Application\Sonata\NewsBundle\Entity\Post',
249
            'Sonata\NewsBundle\Controller\PostAdminController'
250
        );
251
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
252
        $securityHandler->isGranted($admin, 'EDIT_ROLE', $admin)->willReturn(true);
253
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
254
        $customExtension->getAccessMapping($admin)->willReturn(
255
            ['edit_action' => ['EDIT_ROLE']]
256
        );
257
        $admin->addExtension($customExtension->reveal());
258
        $admin->setSecurityHandler($securityHandler->reveal());
259
260
        $this->assertTrue($admin->hasAccess('edit_action'));
261
    }
262
263
    /**
264
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChild
265
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::addChild
266
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChild
267
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::isChild
268
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChildren
269
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChildren
270
     */
271
    public function testChildren(): void
272
    {
273
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
274
        $this->assertFalse($postAdmin->hasChildren());
275
        $this->assertFalse($postAdmin->hasChild('comment'));
276
277
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
278
        $postAdmin->addChild($commentAdmin, 'post');
279
280
        $this->assertTrue($postAdmin->hasChildren());
281
        $this->assertTrue($postAdmin->hasChild('sonata.post.admin.comment'));
282
283
        $this->assertSame('sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getCode());
284
        $this->assertSame('sonata.post.admin.post|sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getBaseCodeRoute());
285
        $this->assertSame($postAdmin, $postAdmin->getChild('sonata.post.admin.comment')->getParent());
286
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
287
288
        $this->assertFalse($postAdmin->isChild());
289
        $this->assertTrue($commentAdmin->isChild());
290
291
        $this->assertSame(['sonata.post.admin.comment' => $commentAdmin], $postAdmin->getChildren());
292
    }
293
294
    /**
295
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configure
296
     */
297
    public function testConfigure(): void
298
    {
299
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
300
        $this->assertNotNull($admin->getUniqid());
301
302
        $admin->initialize();
303
        $this->assertNotNull($admin->getUniqid());
304
        $this->assertSame('Post', $admin->getClassnameLabel());
305
306
        $admin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
307
        $admin->setClassnameLabel('postcomment');
308
309
        $admin->initialize();
310
        $this->assertSame('postcomment', $admin->getClassnameLabel());
311
    }
312
313
    public function testConfigureWithValidParentAssociationMapping(): void
314
    {
315
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
316
        $admin->setParentAssociationMapping('Category');
317
318
        $admin->initialize();
319
        $this->assertSame('Category', $admin->getParentAssociationMapping());
320
    }
321
322
    public function provideGetBaseRoutePattern()
323
    {
324
        return [
325
            [
326
                'Application\Sonata\NewsBundle\Entity\Post',
327
                '/sonata/news/post',
328
            ],
329
            [
330
                'Application\Sonata\NewsBundle\Document\Post',
331
                '/sonata/news/post',
332
            ],
333
            [
334
                'MyApplication\MyBundle\Entity\Post',
335
                '/myapplication/my/post',
336
            ],
337
            [
338
                'MyApplication\MyBundle\Entity\Post\Category',
339
                '/myapplication/my/post-category',
340
            ],
341
            [
342
                'MyApplication\MyBundle\Entity\Product\Category',
343
                '/myapplication/my/product-category',
344
            ],
345
            [
346
                'MyApplication\MyBundle\Entity\Other\Product\Category',
347
                '/myapplication/my/other-product-category',
348
            ],
349
            [
350
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
351
                '/cmf/foo/menu',
352
            ],
353
            [
354
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
355
                '/cmf/foo/menu',
356
            ],
357
            [
358
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
359
                '/symfony/barbar/menu',
360
            ],
361
            [
362
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
363
                '/symfony/barbar/menu-item',
364
            ],
365
            [
366
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
367
                '/cmf/foo/menu',
368
            ],
369
            [
370
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
371
                '/cmf/foo/menu',
372
            ],
373
            [
374
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
375
                '/cmf/foo/menu',
376
            ],
377
            [
378
                'AppBundle\Entity\User',
379
                '/app/user',
380
            ],
381
            [
382
                'App\Entity\User',
383
                '/app/user',
384
            ],
385
        ];
386
    }
387
388
    /**
389
     * @dataProvider provideGetBaseRoutePattern
390
     */
391
    public function testGetBaseRoutePattern(string $objFqn, string $expected): void
392
    {
393
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
394
        $this->assertSame($expected, $admin->getBaseRoutePattern());
395
    }
396
397
    /**
398
     * @dataProvider provideGetBaseRoutePattern
399
     */
400
    public function testGetBaseRoutePatternWithChildAdmin(string $objFqn, string $expected): void
401
    {
402
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
403
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
404
        $commentAdmin->setParent($postAdmin);
405
406
        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
407
    }
408
409
    /**
410
     * @dataProvider provideGetBaseRoutePattern
411
     */
412
    public function testGetBaseRoutePatternWithTwoNestedChildAdmin(string $objFqn, string $expected): void
413
    {
414
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
415
        $commentAdmin = new CommentAdmin(
416
            'sonata.post.admin.comment',
417
            'Application\Sonata\NewsBundle\Entity\Comment',
418
            'Sonata\NewsBundle\Controller\CommentAdminController'
419
        );
420
        $commentVoteAdmin = new CommentVoteAdmin(
421
            'sonata.post.admin.comment_vote',
422
            'Application\Sonata\NewsBundle\Entity\CommentVote',
423
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
424
        );
425
        $commentAdmin->setParent($postAdmin);
426
        $commentVoteAdmin->setParent($commentAdmin);
427
428
        $this->assertSame($expected.'/{id}/comment/{childId}/commentvote', $commentVoteAdmin->getBaseRoutePattern());
429
    }
430
431
    public function testGetBaseRoutePatternWithSpecifedPattern(): void
432
    {
433
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostWithCustomRouteAdminController');
434
435
        $this->assertSame('/post-custom', $postAdmin->getBaseRoutePattern());
436
    }
437
438
    public function testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern(): void
439
    {
440
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
441
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
442
        $commentAdmin->setParent($postAdmin);
443
444
        $this->assertSame('/sonata/news/post/{id}/comment-custom', $commentAdmin->getBaseRoutePattern());
445
    }
446
447
    public function testGetBaseRoutePatternWithUnreconizedClassname(): void
448
    {
449
        $this->expectException(\RuntimeException::class);
450
451
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
452
        $admin->getBaseRoutePattern();
453
    }
454
455
    public function provideGetBaseRouteName()
456
    {
457
        return [
458
            [
459
                'Application\Sonata\NewsBundle\Entity\Post',
460
                'admin_sonata_news_post',
461
            ],
462
            [
463
                'Application\Sonata\NewsBundle\Document\Post',
464
                'admin_sonata_news_post',
465
            ],
466
            [
467
                'MyApplication\MyBundle\Entity\Post',
468
                'admin_myapplication_my_post',
469
            ],
470
            [
471
                'MyApplication\MyBundle\Entity\Post\Category',
472
                'admin_myapplication_my_post_category',
473
            ],
474
            [
475
                'MyApplication\MyBundle\Entity\Product\Category',
476
                'admin_myapplication_my_product_category',
477
            ],
478
            [
479
                'MyApplication\MyBundle\Entity\Other\Product\Category',
480
                'admin_myapplication_my_other_product_category',
481
            ],
482
            [
483
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
484
                'admin_cmf_foo_menu',
485
            ],
486
            [
487
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
488
                'admin_cmf_foo_menu',
489
            ],
490
            [
491
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
492
                'admin_symfony_barbar_menu',
493
            ],
494
            [
495
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
496
                'admin_symfony_barbar_menu_item',
497
            ],
498
            [
499
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
500
                'admin_cmf_foo_menu',
501
            ],
502
            [
503
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
504
                'admin_cmf_foo_menu',
505
            ],
506
            [
507
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
508
                'admin_cmf_foo_menu',
509
            ],
510
            [
511
                'AppBundle\Entity\User',
512
                'admin_app_user',
513
            ],
514
            [
515
                'App\Entity\User',
516
                'admin_app_user',
517
            ],
518
        ];
519
    }
520
521
    /**
522
     * @dataProvider provideGetBaseRouteName
523
     */
524
    public function testGetBaseRouteName(string $objFqn, string $expected): void
525
    {
526
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
527
528
        $this->assertSame($expected, $admin->getBaseRouteName());
529
    }
530
531
    /**
532
     * @group legacy
533
     * @expectedDeprecation Calling "addChild" without second argument is deprecated since sonata-project/admin-bundle 3.35 and will not be allowed in 4.0.
534
     * @dataProvider provideGetBaseRouteName
535
     */
536
    public function testGetBaseRouteNameWithChildAdmin(string $objFqn, string $expected): void
537
    {
538
        $routeGenerator = new DefaultRouteGenerator(
539
            $this->createMock(RouterInterface::class),
540
            new RoutesCache($this->cacheTempFolder, true)
541
        );
542
543
        $container = new Container();
544
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
545
546
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
547
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
548
        $container->set('sonata.post.admin.post', $postAdmin);
549
        $postAdmin->setConfigurationPool($pool);
550
        $postAdmin->setRouteBuilder($pathInfo);
551
        $postAdmin->setRouteGenerator($routeGenerator);
552
        $postAdmin->initialize();
553
554
        $commentAdmin = new CommentAdmin(
555
            'sonata.post.admin.comment',
556
            'Application\Sonata\NewsBundle\Entity\Comment',
557
            'Sonata\NewsBundle\Controller\CommentAdminController'
558
        );
559
        $container->set('sonata.post.admin.comment', $commentAdmin);
560
        $commentAdmin->setConfigurationPool($pool);
561
        $commentAdmin->setRouteBuilder($pathInfo);
562
        $commentAdmin->setRouteGenerator($routeGenerator);
563
        $commentAdmin->initialize();
564
565
        $postAdmin->addChild($commentAdmin, 'post');
566
567
        $commentVoteAdmin = new CommentVoteAdmin(
568
            'sonata.post.admin.comment_vote',
569
            'Application\Sonata\NewsBundle\Entity\CommentVote',
570
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
571
        );
572
573
        $container->set('sonata.post.admin.comment_vote', $commentVoteAdmin);
574
        $commentVoteAdmin->setConfigurationPool($pool);
575
        $commentVoteAdmin->setRouteBuilder($pathInfo);
576
        $commentVoteAdmin->setRouteGenerator($routeGenerator);
577
        $commentVoteAdmin->initialize();
578
579
        $commentAdmin->addChild($commentVoteAdmin);
580
        $pool->setAdminServiceIds([
581
            'sonata.post.admin.post',
582
            'sonata.post.admin.comment',
583
            'sonata.post.admin.comment_vote',
584
        ]);
585
586
        $this->assertSame($expected.'_comment', $commentAdmin->getBaseRouteName());
587
588
        $this->assertTrue($postAdmin->hasRoute('show'));
589
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
590
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.show'));
591
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment|sonata.post.admin.comment_vote.show'));
592
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment.list'));
593
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment|sonata.post.admin.comment_vote.list'));
594
        $this->assertFalse($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.edit'));
595
        $this->assertFalse($commentAdmin->hasRoute('edit'));
596
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
597
598
        /*
599
         * Test the route name from request
600
         */
601
        $postListRequest = new Request(
602
            [],
603
            [],
604
            [
605
                '_route' => $postAdmin->getBaseRouteName().'_list',
606
            ]
607
        );
608
609
        $postAdmin->setRequest($postListRequest);
610
        $commentAdmin->setRequest($postListRequest);
611
612
        $this->assertTrue($postAdmin->isCurrentRoute('list'));
613
        $this->assertFalse($postAdmin->isCurrentRoute('create'));
614
        $this->assertFalse($commentAdmin->isCurrentRoute('list'));
615
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('list'));
616
        $this->assertTrue($commentAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
617
        $this->assertFalse($commentAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
618
        $this->assertTrue($commentVoteAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
619
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
620
    }
621
622
    public function testGetBaseRouteNameWithUnreconizedClassname(): void
623
    {
624
        $this->expectException(\RuntimeException::class);
625
626
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
627
        $admin->getBaseRouteName();
628
    }
629
630
    public function testGetBaseRouteNameWithSpecifiedName(): void
631
    {
632
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
633
634
        $this->assertSame('post_custom', $postAdmin->getBaseRouteName());
635
    }
636
637
    public function testGetBaseRouteNameWithChildAdminAndWithSpecifiedName(): void
638
    {
639
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
640
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
641
        $commentAdmin->setParent($postAdmin);
642
643
        $this->assertSame('admin_sonata_news_post_comment_custom', $commentAdmin->getBaseRouteName());
644
    }
645
646
    public function testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName(): void
647
    {
648
        $postAdmin = new PostAdmin(
649
            'sonata.post.admin.post',
650
            'Application\Sonata\NewsBundle\Entity\Post',
651
            'Sonata\NewsBundle\Controller\PostAdminController'
652
        );
653
        $commentAdmin = new CommentWithCustomRouteAdmin(
654
            'sonata.post.admin.comment_with_custom_route',
655
            'Application\Sonata\NewsBundle\Entity\Comment',
656
            'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController'
657
        );
658
        $commentVoteAdmin = new CommentVoteAdmin(
659
            'sonata.post.admin.comment_vote',
660
            'Application\Sonata\NewsBundle\Entity\CommentVote',
661
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
662
        );
663
        $commentAdmin->setParent($postAdmin);
664
        $commentVoteAdmin->setParent($commentAdmin);
665
666
        $this->assertSame('admin_sonata_news_post_comment_custom_commentvote', $commentVoteAdmin->getBaseRouteName());
667
    }
668
669
    /**
670
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setUniqid
671
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getUniqid
672
     */
673
    public function testSetUniqid(): void
674
    {
675
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
676
677
        $uniqid = uniqid();
678
        $admin->setUniqid($uniqid);
679
680
        $this->assertSame($uniqid, $admin->getUniqid());
681
    }
682
683
    public function testToString(): void
684
    {
685
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
686
687
        $s = new \stdClass();
688
689
        $this->assertNotEmpty($admin->toString($s));
690
691
        $s = new FooToString();
692
        $this->assertSame('salut', $admin->toString($s));
693
694
        // To string method is implemented, but returns null
695
        $s = new FooToStringNull();
696
        $this->assertNotEmpty($admin->toString($s));
697
698
        $this->assertSame('', $admin->toString(false));
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
699
    }
700
701
    public function testIsAclEnabled(): void
702
    {
703
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
704
705
        $this->assertFalse($postAdmin->isAclEnabled());
706
707
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
708
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
709
        $this->assertTrue($commentAdmin->isAclEnabled());
710
    }
711
712
    /**
713
     * @group legacy
714
     *
715
     * @expectedDeprecation Calling Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode() when there is no active subclass is deprecated since sonata-project/admin-bundle 3.52 and will throw an exception in 4.0. Use Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass() to know if there is an active subclass.
716
     *
717
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
718
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
719
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
720
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
721
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
722
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
723
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
724
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
725
     */
726
    public function testSubClass(): void
727
    {
728
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
729
        $admin = new PostAdmin(
730
            'sonata.post.admin.post',
731
            Post::class,
732
            'Sonata\NewsBundle\Controller\PostAdminController'
733
        );
734
        $this->assertFalse($admin->hasSubClass('test'));
735
        $this->assertFalse($admin->hasActiveSubClass());
736
        $this->assertCount(0, $admin->getSubClasses());
737
        $this->assertNull($admin->getActiveSubClass());
738
        $this->assertNull($admin->getActiveSubclassCode());
739
        $this->assertSame(Post::class, $admin->getClass());
740
741
        // Just for the record, if there is no inheritance set, the getSubject is not used
742
        // the getSubject can also lead to some issue
743
        $admin->setSubject(new BlogPost());
744
        $this->assertSame(BlogPost::class, $admin->getClass());
745
746
        $admin->setSubClasses([
747
            'extended1' => 'NewsBundle\Entity\PostExtended1',
748
            'extended2' => 'NewsBundle\Entity\PostExtended2',
749
        ]);
750
        $this->assertFalse($admin->hasSubClass('test'));
751
        $this->assertTrue($admin->hasSubClass('extended1'));
752
        $this->assertFalse($admin->hasActiveSubClass());
753
        $this->assertCount(2, $admin->getSubClasses());
754
        // NEXT_MAJOR: remove the following 2 `assertNull()` assertions
755
        $this->assertNull($admin->getActiveSubClass());
756
        $this->assertNull($admin->getActiveSubclassCode());
757
        $this->assertSame(
758
            BlogPost::class,
759
            $admin->getClass(),
760
            'When there is no subclass in the query the class parameter should be returned'
761
        );
762
763
        $request = new Request(['subclass' => 'extended1']);
764
        $admin->setRequest($request);
765
        $this->assertFalse($admin->hasSubClass('test'));
766
        $this->assertTrue($admin->hasSubClass('extended1'));
767
        $this->assertTrue($admin->hasActiveSubClass());
768
        $this->assertCount(2, $admin->getSubClasses());
769
        $this->assertSame(
770
            'NewsBundle\Entity\PostExtended1',
771
            $admin->getActiveSubClass(),
772
            'It should return the curently active sub class.'
773
        );
774
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
775
        $this->assertSame(
776
            'NewsBundle\Entity\PostExtended1',
777
            $admin->getClass(),
778
            'getClass() should return the name of the sub class when passed through a request query parameter.'
779
        );
780
781
        $request->query->set('subclass', 'inject');
782
783
        $this->assertNull($admin->getActiveSubclassCode());
784
        // NEXT_MAJOR: remove the previous `assertNull()` assertion and uncomment the following lines
785
        // $this->expectException(\LogicException::class);
786
        // $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
787
    }
788
789
    /**
790
     * @group legacy
791
     *
792
     * @expectedDeprecation Calling Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode() when there is no active subclass is deprecated since sonata-project/admin-bundle 3.52 and will throw an exception in 4.0. Use Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass() to know if there is an active subclass.
793
     */
794
    public function testNonExistantSubclass(): void
795
    {
796
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
797
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
798
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
799
800
        $admin->setRequest(new Request(['subclass' => 'inject']));
801
802
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
803
804
        $this->assertTrue($admin->hasActiveSubClass());
805
806
        $this->expectException(\RuntimeException::class);
807
808
        $admin->getActiveSubClass();
809
    }
810
811
    /**
812
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
813
     */
814
    public function testOnlyOneSubclassNeededToBeActive(): void
815
    {
816
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
817
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
818
        $request = new Request(['subclass' => 'extended1']);
819
        $admin->setRequest($request);
820
        $this->assertTrue($admin->hasActiveSubClass());
821
    }
822
823
    /**
824
     * @group legacy
825
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since sonata-project/admin-bundle 3.30 and will be removed in 4.0.
826
     */
827
    public function testAddSubClassIsDeprecated(): void
828
    {
829
        $admin = new PostAdmin(
830
            'sonata.post.admin.post',
831
            Post::class,
832
            'Sonata\NewsBundle\Controller\PostAdminController'
833
        );
834
        $admin->addSubClass('whatever');
835
    }
836
837
    /**
838
     * @group legacy
839
     */
840
    public function testGetPerPageOptions(): void
841
    {
842
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
843
844
        $perPageOptions = $admin->getPerPageOptions();
845
846
        foreach ($perPageOptions as $perPage) {
847
            $this->assertSame(0, $perPage % 4);
848
        }
849
850
        $admin->setPerPageOptions([500, 1000]);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...in::setPerPageOptions() has been deprecated with message: since sonata-project/admin-bundle 3.67, to be removed in 4.0. Set custom per page options.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
851
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
852
    }
853
854
    public function testGetLabelTranslatorStrategy(): void
855
    {
856
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
857
858
        $this->assertNull($admin->getLabelTranslatorStrategy());
859
860
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
861
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
862
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
863
    }
864
865
    public function testGetRouteBuilder(): void
866
    {
867
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
868
869
        $this->assertNull($admin->getRouteBuilder());
870
871
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
872
        $admin->setRouteBuilder($routeBuilder);
873
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
874
    }
875
876
    public function testGetMenuFactory(): void
877
    {
878
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
879
880
        $this->assertNull($admin->getMenuFactory());
881
882
        $menuFactory = $this->createMock(FactoryInterface::class);
883
        $admin->setMenuFactory($menuFactory);
884
        $this->assertSame($menuFactory, $admin->getMenuFactory());
885
    }
886
887
    public function testGetExtensions(): void
888
    {
889
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
890
891
        $this->assertSame([], $admin->getExtensions());
892
893
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
894
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
895
896
        $admin->addExtension($adminExtension1);
897
        $admin->addExtension($adminExtension2);
898
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
899
    }
900
901
    public function testGetFilterTheme(): void
902
    {
903
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
904
905
        $this->assertSame([], $admin->getFilterTheme());
906
907
        $admin->setFilterTheme(['FooTheme']);
908
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
909
    }
910
911
    public function testGetFormTheme(): void
912
    {
913
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
914
915
        $this->assertSame([], $admin->getFormTheme());
916
917
        $admin->setFormTheme(['FooTheme']);
918
919
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
920
    }
921
922
    public function testGetValidator(): void
923
    {
924
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
925
926
        $this->assertNull($admin->getValidator());
927
928
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
929
930
        $admin->setValidator($validator);
931
        $this->assertSame($validator, $admin->getValidator());
932
    }
933
934
    public function testGetSecurityHandler(): void
935
    {
936
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
937
938
        $this->assertNull($admin->getSecurityHandler());
939
940
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
941
        $admin->setSecurityHandler($securityHandler);
942
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
943
    }
944
945
    public function testGetSecurityInformation(): void
946
    {
947
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
948
949
        $this->assertSame([], $admin->getSecurityInformation());
950
951
        $securityInformation = [
952
            'GUEST' => ['VIEW', 'LIST'],
953
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
954
        ];
955
956
        $admin->setSecurityInformation($securityInformation);
957
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
958
    }
959
960
    public function testGetManagerType(): void
961
    {
962
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
963
964
        $this->assertNull($admin->getManagerType());
965
966
        $admin->setManagerType('foo_orm');
967
        $this->assertSame('foo_orm', $admin->getManagerType());
968
    }
969
970
    public function testGetModelManager(): void
971
    {
972
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
973
974
        $this->assertNull($admin->getModelManager());
975
976
        $modelManager = $this->createMock(ModelManagerInterface::class);
977
978
        $admin->setModelManager($modelManager);
979
        $this->assertSame($modelManager, $admin->getModelManager());
980
    }
981
982
    /**
983
     * NEXT_MAJOR: remove this method.
984
     *
985
     * @group legacy
986
     */
987
    public function testGetBaseCodeRoute(): void
988
    {
989
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
990
991
        $this->assertSame('', $admin->getBaseCodeRoute());
992
993
        $admin->setBaseCodeRoute('foo');
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...min::setBaseCodeRoute() has been deprecated with message: This method is deprecated since sonata-project/admin-bundle 3.24 and will be removed in 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
994
        $this->assertSame('foo', $admin->getBaseCodeRoute());
995
    }
996
997
    // NEXT_MAJOR: uncomment this method.
998
    // public function testGetBaseCodeRoute()
999
    // {
1000
    //     $postAdmin = new PostAdmin(
1001
    //         'sonata.post.admin.post',
1002
    //         'NewsBundle\Entity\Post',
1003
    //         'Sonata\NewsBundle\Controller\PostAdminController'
1004
    //     );
1005
    //     $commentAdmin = new CommentAdmin(
1006
    //         'sonata.post.admin.comment',
1007
    //         'Application\Sonata\NewsBundle\Entity\Comment',
1008
    //         'Sonata\NewsBundle\Controller\CommentAdminController'
1009
    //     );
1010
    //
1011
    //     $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
1012
    //
1013
    //     $postAdmin->addChild($commentAdmin);
1014
    //
1015
    //     $this->assertSame(
1016
    //         'sonata.post.admin.post|sonata.post.admin.comment',
1017
    //         $commentAdmin->getBaseCodeRoute()
1018
    //     );
1019
    // }
1020
1021
    public function testGetRouteGenerator(): void
1022
    {
1023
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1024
1025
        $this->assertNull($admin->getRouteGenerator());
1026
1027
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1028
1029
        $admin->setRouteGenerator($routeGenerator);
1030
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1031
    }
1032
1033
    public function testGetConfigurationPool(): void
1034
    {
1035
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1036
1037
        $this->assertNull($admin->getConfigurationPool());
1038
1039
        $pool = $this->getMockBuilder(Pool::class)
1040
            ->disableOriginalConstructor()
1041
            ->getMock();
1042
1043
        $admin->setConfigurationPool($pool);
1044
        $this->assertSame($pool, $admin->getConfigurationPool());
1045
    }
1046
1047
    public function testGetShowBuilder(): void
1048
    {
1049
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1050
1051
        $this->assertNull($admin->getShowBuilder());
1052
1053
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1054
1055
        $admin->setShowBuilder($showBuilder);
1056
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1057
    }
1058
1059
    public function testGetListBuilder(): void
1060
    {
1061
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1062
1063
        $this->assertNull($admin->getListBuilder());
1064
1065
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1066
1067
        $admin->setListBuilder($listBuilder);
1068
        $this->assertSame($listBuilder, $admin->getListBuilder());
1069
    }
1070
1071
    public function testGetDatagridBuilder(): void
1072
    {
1073
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1074
1075
        $this->assertNull($admin->getDatagridBuilder());
1076
1077
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1078
1079
        $admin->setDatagridBuilder($datagridBuilder);
1080
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1081
    }
1082
1083
    public function testGetFormContractor(): void
1084
    {
1085
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1086
1087
        $this->assertNull($admin->getFormContractor());
1088
1089
        $formContractor = $this->createMock(FormContractorInterface::class);
1090
1091
        $admin->setFormContractor($formContractor);
1092
        $this->assertSame($formContractor, $admin->getFormContractor());
1093
    }
1094
1095
    public function testGetRequest(): void
1096
    {
1097
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1098
1099
        $this->assertFalse($admin->hasRequest());
1100
1101
        $request = new Request();
1102
1103
        $admin->setRequest($request);
1104
        $this->assertSame($request, $admin->getRequest());
1105
        $this->assertTrue($admin->hasRequest());
1106
    }
1107
1108
    public function testGetRequestWithException(): void
1109
    {
1110
        $this->expectException(\RuntimeException::class);
1111
        $this->expectExceptionMessage('The Request object has not been set');
1112
1113
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1114
        $admin->getRequest();
1115
    }
1116
1117
    public function testGetTranslationDomain(): void
1118
    {
1119
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1120
1121
        $this->assertSame('messages', $admin->getTranslationDomain());
1122
1123
        $admin->setTranslationDomain('foo');
1124
        $this->assertSame('foo', $admin->getTranslationDomain());
1125
    }
1126
1127
    /**
1128
     * @group legacy
1129
     */
1130
    public function testGetTranslator(): void
1131
    {
1132
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1133
1134
        $this->assertNull($admin->getTranslator());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::getTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1135
1136
        $translator = $this->createMock(TranslatorInterface::class);
1137
1138
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1139
        $this->assertSame($translator, $admin->getTranslator());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::getTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1140
    }
1141
1142
    public function testGetShowGroups(): void
1143
    {
1144
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1145
1146
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1147
        $this->assertFalse($admin->getShowGroups('sonata_deprecation_mute'));
1148
1149
        $groups = ['foo', 'bar', 'baz'];
1150
1151
        $admin->setShowGroups($groups);
1152
        $this->assertSame($groups, $admin->getShowGroups());
1153
    }
1154
1155
    public function testGetFormGroups(): void
1156
    {
1157
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1158
1159
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1160
        $this->assertFalse($admin->getFormGroups('sonata_deprecation_mute'));
1161
1162
        $groups = ['foo', 'bar', 'baz'];
1163
1164
        $admin->setFormGroups($groups);
1165
        $this->assertSame($groups, $admin->getFormGroups());
1166
    }
1167
1168
    public function testGetMaxPageLinks(): void
1169
    {
1170
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1171
1172
        $this->assertSame(25, $admin->getMaxPageLinks());
1173
1174
        $admin->setMaxPageLinks(14);
1175
        $this->assertSame(14, $admin->getMaxPageLinks());
1176
    }
1177
1178
    /**
1179
     * @group legacy
1180
     */
1181
    public function testGetMaxPerPage(): void
1182
    {
1183
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1184
1185
        $this->assertSame(32, $admin->getMaxPerPage());
1186
1187
        $admin->setMaxPerPage(94);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setMaxPerPage() has been deprecated with message: since sonata-project/admin-bundle 3.67, to be removed in 4.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1188
        $this->assertSame(94, $admin->getMaxPerPage());
1189
    }
1190
1191
    public function testGetLabel(): void
1192
    {
1193
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1194
1195
        $this->assertNull($admin->getLabel());
1196
1197
        $admin->setLabel('FooLabel');
1198
        $this->assertSame('FooLabel', $admin->getLabel());
1199
    }
1200
1201
    public function testGetBaseController(): void
1202
    {
1203
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1204
1205
        $this->assertSame('Sonata\NewsBundle\Controller\PostAdminController', $admin->getBaseControllerName());
1206
1207
        $admin->setBaseControllerName('Sonata\NewsBundle\Controller\FooAdminController');
1208
        $this->assertSame('Sonata\NewsBundle\Controller\FooAdminController', $admin->getBaseControllerName());
1209
    }
1210
1211
    public function testGetTemplates(): void
1212
    {
1213
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1214
1215
        $templates = [
1216
            'list' => '@FooAdmin/CRUD/list.html.twig',
1217
            'show' => '@FooAdmin/CRUD/show.html.twig',
1218
            'edit' => '@FooAdmin/CRUD/edit.html.twig',
1219
        ];
1220
1221
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1222
        $templateRegistry->getTemplates()->shouldBeCalled()->willReturn($templates);
1223
1224
        $admin->setTemplateRegistry($templateRegistry->reveal());
1225
1226
        $this->assertSame($templates, $admin->getTemplates());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...ctAdmin::getTemplates() has been deprecated with message: since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

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

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

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

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1241
    }
1242
1243
    public function testGetIdParameter(): void
1244
    {
1245
        $postAdmin = new PostAdmin(
1246
            'sonata.post.admin.post',
1247
            'NewsBundle\Entity\Post',
1248
            'Sonata\NewsBundle\Controller\PostAdminController'
1249
        );
1250
1251
        $this->assertSame('id', $postAdmin->getIdParameter());
1252
        $this->assertFalse($postAdmin->isChild());
1253
1254
        $commentAdmin = new CommentAdmin(
1255
            'sonata.post.admin.comment',
1256
            'Application\Sonata\NewsBundle\Entity\Comment',
1257
            'Sonata\NewsBundle\Controller\CommentAdminController'
1258
        );
1259
        $commentAdmin->setParent($postAdmin);
1260
1261
        $this->assertTrue($commentAdmin->isChild());
1262
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1263
1264
        $commentVoteAdmin = new CommentVoteAdmin(
1265
            'sonata.post.admin.comment_vote',
1266
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1267
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
1268
        );
1269
        $commentVoteAdmin->setParent($commentAdmin);
1270
1271
        $this->assertTrue($commentVoteAdmin->isChild());
1272
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1273
    }
1274
1275
    public function testGetExportFormats(): void
1276
    {
1277
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1278
1279
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1280
    }
1281
1282
    public function testGetUrlsafeIdentifier(): void
1283
    {
1284
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1285
1286
        $model = new \stdClass();
1287
1288
        $modelManager = $this->createMock(ModelManagerInterface::class);
1289
        $modelManager->expects($this->once())
1290
            ->method('getUrlSafeIdentifier')
1291
            ->with($this->equalTo($model))
1292
            ->willReturn('foo');
1293
        $admin->setModelManager($modelManager);
1294
1295
        $this->assertSame('foo', $admin->getUrlSafeIdentifier($model));
1296
    }
1297
1298
    public function testDeterminedPerPageValue(): void
1299
    {
1300
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1301
1302
        $this->assertFalse($admin->determinedPerPageValue('foo'));
1303
        $this->assertFalse($admin->determinedPerPageValue(123));
1304
        $this->assertTrue($admin->determinedPerPageValue(16));
1305
    }
1306
1307
    public function testIsGranted(): void
1308
    {
1309
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1310
        $modelManager = $this->createStub(ModelManagerInterface::class);
1311
        $modelManager
1312
            ->method('getNormalizedIdentifier')
1313
            ->willReturnCallback(static function (?object $model = null): ?string {
1314
                return $model ? $model->id : null;
1315
            });
1316
1317
        $admin->setModelManager($modelManager);
1318
1319
        $entity1 = new \stdClass();
1320
        $entity1->id = '1';
1321
1322
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1323
        $securityHandler
1324
            ->expects($this->exactly(6))
1325
            ->method('isGranted')
1326
            ->willReturnCallback(static function (
1327
                AdminInterface $adminIn,
1328
                string $attributes,
1329
                ?object $object = null
1330
            ) use (
1331
                $admin,
1332
                $entity1
1333
            ): bool {
1334
                return $admin === $adminIn && 'FOO' === $attributes &&
1335
                    ($object === $admin || $object === $entity1);
1336
            });
1337
1338
        $admin->setSecurityHandler($securityHandler);
1339
1340
        $this->assertTrue($admin->isGranted('FOO'));
1341
        $this->assertTrue($admin->isGranted('FOO'));
1342
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1343
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1344
        $this->assertFalse($admin->isGranted('BAR'));
1345
        $this->assertFalse($admin->isGranted('BAR'));
1346
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1347
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1348
1349
        $entity2 = new \stdClass();
1350
        $entity2->id = '2';
1351
1352
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1353
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1354
1355
        $entity3 = new \stdClass();
1356
        $entity3->id = '3';
1357
1358
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1359
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1360
    }
1361
1362
    public function testSupportsPreviewMode(): void
1363
    {
1364
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1365
1366
        $this->assertFalse($admin->supportsPreviewMode());
1367
    }
1368
1369
    public function testGetPermissionsShow(): void
1370
    {
1371
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1372
1373
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1374
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1375
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1376
    }
1377
1378
    public function testShowIn(): void
1379
    {
1380
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1381
1382
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1383
        $securityHandler
1384
            ->method('isGranted')
1385
            ->willReturnCallback(static function (AdminInterface $adminIn, array $attributes, $object = null) use ($admin): bool {
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1386
                return $admin === $adminIn && $attributes === ['LIST'];
1387
            });
1388
1389
        $admin->setSecurityHandler($securityHandler);
1390
1391
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1392
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1393
        $this->assertTrue($admin->showIn('foo'));
1394
    }
1395
1396
    public function testGetObjectIdentifier(): void
1397
    {
1398
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1399
1400
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1401
    }
1402
1403
    /**
1404
     * @group legacy
1405
     */
1406
    public function testTrans(): void
1407
    {
1408
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1409
        $admin->setTranslationDomain('fooMessageDomain');
1410
1411
        $translator = $this->createMock(TranslatorInterface::class);
1412
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1413
1414
        $translator->expects($this->once())
1415
            ->method('trans')
1416
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1417
            ->willReturn('fooTranslated');
1418
1419
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1420
    }
1421
1422
    /**
1423
     * @group legacy
1424
     */
1425
    public function testTransWithMessageDomain(): void
1426
    {
1427
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1428
1429
        $translator = $this->createMock(TranslatorInterface::class);
1430
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1431
1432
        $translator->expects($this->once())
1433
            ->method('trans')
1434
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1435
            ->willReturn('fooTranslated');
1436
1437
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1438
    }
1439
1440
    /**
1441
     * @group legacy
1442
     */
1443
    public function testTransChoice(): void
1444
    {
1445
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1446
        $admin->setTranslationDomain('fooMessageDomain');
1447
1448
        $translator = $this->createMock(TranslatorInterface::class);
1449
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1450
1451
        $translator->expects($this->once())
1452
            ->method('transChoice')
1453
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1454
            ->willReturn('fooTranslated');
1455
1456
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::transChoice() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1457
    }
1458
1459
    /**
1460
     * @group legacy
1461
     */
1462
    public function testTransChoiceWithMessageDomain(): void
1463
    {
1464
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1465
1466
        $translator = $this->createMock(TranslatorInterface::class);
1467
        $admin->setTranslator($translator);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setTranslator() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1468
1469
        $translator->expects($this->once())
1470
            ->method('transChoice')
1471
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1472
            ->willReturn('fooTranslated');
1473
1474
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2, ['name' => 'Andrej'], 'fooMessageDomain'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::transChoice() has been deprecated with message: since sonata-project/admin-bundle 3.9, to be removed with 4.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1475
    }
1476
1477
    public function testSetFilterPersister(): void
1478
    {
1479
        $admin = new class('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController') extends PostAdmin {
1480
            public function persistFilters(): bool
1481
            {
1482
                return $this->persistFilters;
0 ignored issues
show
Deprecated Code introduced by
The property Sonata\AdminBundle\Admin...tAdmin::$persistFilters has been deprecated with message: since sonata-project/admin-bundle 3.34, to be removed in 4.0.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1483
            }
1484
        };
1485
1486
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1487
1488
        $admin->setFilterPersister($filterPersister);
1489
        $this->assertTrue($admin->persistFilters());
1490
    }
1491
1492
    public function testGetRootCode(): void
1493
    {
1494
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1495
1496
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1497
1498
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1499
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1500
        $parentFieldDescription->expects($this->once())
1501
            ->method('getAdmin')
1502
            ->willReturn($parentAdmin);
1503
1504
        $this->assertFalse($admin->hasParentFieldDescription());
1505
        $admin->setParentFieldDescription($parentFieldDescription);
1506
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1507
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1508
    }
1509
1510
    public function testGetRoot(): void
1511
    {
1512
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1513
1514
        $this->assertSame($admin, $admin->getRoot());
1515
1516
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1517
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1518
        $parentFieldDescription->expects($this->once())
1519
            ->method('getAdmin')
1520
            ->willReturn($parentAdmin);
1521
1522
        $this->assertFalse($admin->hasParentFieldDescription());
1523
        $admin->setParentFieldDescription($parentFieldDescription);
1524
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1525
        $this->assertSame($parentAdmin, $admin->getRoot());
1526
    }
1527
1528
    public function testGetExportFields(): void
1529
    {
1530
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1531
1532
        $modelManager = $this->createMock(ModelManagerInterface::class);
1533
        $modelManager->expects($this->once())
1534
            ->method('getExportFields')
1535
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1536
            ->willReturn(['foo', 'bar']);
1537
1538
        $admin->setModelManager($modelManager);
1539
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1540
    }
1541
1542
    public function testGetPersistentParametersWithNoExtension(): void
1543
    {
1544
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1545
1546
        $this->assertEmpty($admin->getPersistentParameters());
1547
    }
1548
1549
    public function testGetPersistentParametersWithInvalidExtension(): void
1550
    {
1551
        $this->expectException(\RuntimeException::class);
1552
1553
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1554
1555
        $extension = $this->createMock(AdminExtensionInterface::class);
1556
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn(null);
1557
1558
        $admin->addExtension($extension);
1559
1560
        $admin->getPersistentParameters();
1561
    }
1562
1563
    public function testGetPersistentParametersWithValidExtension(): void
1564
    {
1565
        $expected = [
1566
            'context' => 'foobar',
1567
        ];
1568
1569
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1570
1571
        $extension = $this->createMock(AdminExtensionInterface::class);
1572
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1573
1574
        $admin->addExtension($extension);
1575
1576
        $this->assertSame($expected, $admin->getPersistentParameters());
1577
    }
1578
1579
    public function testGetFormWithNonCollectionParentValue(): void
1580
    {
1581
        $post = new Post();
1582
        $tagAdmin = $this->createTagAdmin($post);
1583
        $tag = $tagAdmin->getSubject();
1584
1585
        $tag->setPosts(null);
1586
        $tagAdmin->getForm();
1587
        $this->assertSame($post, $tag->getPosts());
1588
    }
1589
1590
    public function testGetFormWithCollectionParentValue(): void
1591
    {
1592
        $post = new Post();
1593
        $tagAdmin = $this->createTagAdmin($post);
1594
        $tag = $tagAdmin->getSubject();
1595
1596
        // Case of a doctrine collection
1597
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1598
        $this->assertCount(0, $tag->getPosts());
1599
1600
        $tag->addPost(new Post());
1601
1602
        $this->assertCount(1, $tag->getPosts());
1603
1604
        $tagAdmin->getForm();
1605
1606
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1607
        $this->assertCount(2, $tag->getPosts());
1608
        $this->assertContains($post, $tag->getPosts());
1609
    }
1610
1611
    public function testGetFormWithArrayParentValue(): void
1612
    {
1613
        $post = new Post();
1614
        $tagAdmin = $this->createTagAdmin($post);
1615
        $tag = $tagAdmin->getSubject();
1616
1617
        // Case of an array
1618
        $tag->setPosts([]);
1619
        $this->assertCount(0, $tag->getPosts());
1620
1621
        $tag->addPost(new Post());
1622
1623
        $this->assertCount(1, $tag->getPosts());
1624
1625
        $tagAdmin->getForm();
1626
1627
        $this->assertIsArray($tag->getPosts());
1628
        $this->assertCount(2, $tag->getPosts());
1629
        $this->assertContains($post, $tag->getPosts());
1630
    }
1631
1632
    public function testFormAddPostSubmitEventForPreValidation(): void
1633
    {
1634
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1635
        $object = new \stdClass();
1636
1637
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1638
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1639
1640
        $validator = $this->createMock(ValidatorInterface::class);
1641
        $validator
1642
                ->method('getMetadataFor')
1643
                ->willReturn($this->createMock(MemberMetadata::class));
1644
        $modelAdmin->setValidator($validator);
1645
1646
        $modelManager = $this->createMock(ModelManagerInterface::class);
1647
        $modelManager
1648
            ->method('getNewFieldDescriptionInstance')
1649
            ->willReturn(new FieldDescription());
1650
        $modelAdmin->setModelManager($modelManager);
1651
1652
        // a Admin class to test that preValidate is called
1653
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1654
        $testAdminPreValidate->expects($this->once())
1655
                ->method('preValidate')
1656
                ->with($this->identicalTo($object));
1657
1658
        $event = $this->createMock(FormEvent::class);
1659
        $event
1660
                ->method('getData')
1661
                ->willReturn($object);
1662
1663
        $formBuild = $this->createMock(FormBuilder::class);
1664
        $formBuild->expects($this->once())
1665
                ->method('addEventListener')
1666
                ->with(
1667
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1668
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1669
                        if (\is_callable($callback)) {
1670
                            $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...
1671
                            $closure($event);
1672
1673
                            return true;
1674
                        }
1675
1676
                        return false;
1677
                    }),
1678
                    $this->greaterThan(0)
1679
                );
1680
1681
        $formContractor = $this->createMock(FormContractorInterface::class);
1682
        $formContractor
1683
                ->method('getDefaultOptions')
1684
                ->willReturn([]);
1685
        $formContractor
1686
                ->method('getFormBuilder')
1687
                ->willReturn($formBuild);
1688
1689
        $modelAdmin->setFormContractor($formContractor);
1690
        $modelAdmin->setSubject($object);
1691
        $modelAdmin->defineFormBuilder($formBuild);
1692
        $modelAdmin->getForm();
1693
    }
1694
1695
    public function testCanAddInlineValidationOnlyForGenericMetadata(): void
1696
    {
1697
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1698
        $object = new \stdClass();
1699
1700
        $labelTranslatorStrategy = $this->createStub(LabelTranslatorStrategyInterface::class);
1701
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1702
1703
        $validator = $this->createStub(ValidatorInterface::class);
1704
        $metadata = $this->createStub(PropertyMetadataInterface::class);
1705
        $validator
1706
            ->method('getMetadataFor')
1707
            ->willReturn($metadata);
1708
        $modelAdmin->setValidator($validator);
1709
1710
        $modelManager = $this->createStub(ModelManagerInterface::class);
1711
        $modelManager
1712
            ->method('getNewFieldDescriptionInstance')
1713
            ->willReturn(new FieldDescription());
1714
        $modelAdmin->setModelManager($modelManager);
1715
1716
        $event = $this->createStub(FormEvent::class);
1717
        $event
1718
            ->method('getData')
1719
            ->willReturn($object);
1720
1721
        $formBuild = $this->createStub(FormBuilder::class);
1722
1723
        $formContractor = $this->createStub(FormContractorInterface::class);
1724
        $formContractor
1725
            ->method('getDefaultOptions')
1726
            ->willReturn([]);
1727
        $formContractor
1728
            ->method('getFormBuilder')
1729
            ->willReturn($formBuild);
1730
1731
        $modelAdmin->setFormContractor($formContractor);
1732
        $modelAdmin->setSubject($object);
1733
1734
        $this->expectException(\RuntimeException::class);
1735
        $this->expectExceptionMessage(
1736
            sprintf(
1737
                'Cannot add inline validator for stdClass because its metadata is an instance of %s instead of Symfony\Component\Validator\Mapping\GenericMetadata',
1738
                \get_class($metadata)
1739
            )
1740
        );
1741
1742
        $modelAdmin->defineFormBuilder($formBuild);
1743
    }
1744
1745
    public function testRemoveFieldFromFormGroup(): void
1746
    {
1747
        $formGroups = [
1748
            'foobar' => [
1749
                'fields' => [
1750
                    'foo' => 'foo',
1751
                    'bar' => 'bar',
1752
                ],
1753
            ],
1754
        ];
1755
1756
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1757
        $admin->setFormGroups($formGroups);
1758
1759
        $admin->removeFieldFromFormGroup('foo');
1760
        $this->assertSame($admin->getFormGroups(), [
1761
            'foobar' => [
1762
                'fields' => [
1763
                    'bar' => 'bar',
1764
                ],
1765
            ],
1766
        ]);
1767
1768
        $admin->removeFieldFromFormGroup('bar');
1769
        $this->assertSame($admin->getFormGroups(), []);
1770
    }
1771
1772
    public function testGetFilterParameters(): void
1773
    {
1774
        $authorId = uniqid();
1775
1776
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1777
1778
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1779
        $commentAdmin->setParentAssociationMapping('post.author');
1780
        $commentAdmin->setParent($postAdmin);
1781
1782
        $request = $this->createMock(Request::class);
1783
        $query = $this->createMock(ParameterBag::class);
1784
        $query
1785
            ->method('get')
1786
            ->willReturn([
1787
                'filter' => [
1788
                    '_page' => '1',
1789
                    '_per_page' => '32',
1790
                ],
1791
            ]);
1792
1793
        $request->query = $query;
1794
        $request
1795
            ->method('get')
1796
            ->willReturn($authorId);
1797
1798
        $commentAdmin->setRequest($request);
1799
1800
        $modelManager = $this->createMock(ModelManagerInterface::class);
1801
        $modelManager
1802
            ->method('getDefaultSortValues')
1803
            ->willReturn([]);
1804
1805
        $commentAdmin->setModelManager($modelManager);
1806
1807
        $parameters = $commentAdmin->getFilterParameters();
1808
1809
        $this->assertTrue(isset($parameters['post__author']));
1810
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1811
    }
1812
1813
    public function testGetFilterFieldDescription(): void
1814
    {
1815
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1816
1817
        $fooFieldDescription = new FieldDescription();
1818
        $barFieldDescription = new FieldDescription();
1819
        $bazFieldDescription = new FieldDescription();
1820
1821
        $modelManager = $this->createMock(ModelManagerInterface::class);
1822
        $modelManager->expects($this->exactly(3))
1823
            ->method('getNewFieldDescriptionInstance')
1824
            ->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...
1825
                switch ($name) {
1826
                    case 'foo':
1827
                        $fieldDescription = $fooFieldDescription;
1828
1829
                        break;
1830
1831
                    case 'bar':
1832
                        $fieldDescription = $barFieldDescription;
1833
1834
                        break;
1835
1836
                    case 'baz':
1837
                        $fieldDescription = $bazFieldDescription;
1838
1839
                        break;
1840
1841
                    default:
1842
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1843
                        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...
1844
                }
1845
1846
                $fieldDescription->setName($name);
1847
1848
                return $fieldDescription;
1849
            });
1850
1851
        $modelAdmin->setModelManager($modelManager);
1852
1853
        $pager = $this->createMock(PagerInterface::class);
1854
1855
        $datagrid = $this->createMock(DatagridInterface::class);
1856
        $datagrid->expects($this->once())
1857
            ->method('getPager')
1858
            ->willReturn($pager);
1859
1860
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1861
        $datagridBuilder->expects($this->once())
1862
            ->method('getBaseDatagrid')
1863
            ->with($this->identicalTo($modelAdmin), [])
1864
            ->willReturn($datagrid);
1865
1866
        $datagridBuilder->expects($this->exactly(3))
1867
            ->method('addFilter')
1868
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1869
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1870
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1871
            });
1872
1873
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1874
1875
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1876
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1877
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1878
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1879
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1880
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1881
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1882
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1883
    }
1884
1885
    public function testGetSubjectNoRequest(): void
1886
    {
1887
        $modelManager = $this->createMock(ModelManagerInterface::class);
1888
        $modelManager
1889
            ->expects($this->never())
1890
            ->method('find');
1891
1892
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1893
        $admin->setModelManager($modelManager);
1894
1895
        $this->assertFalse($admin->hasSubject());
1896
    }
1897
1898
    public function testGetSideMenu(): void
1899
    {
1900
        $item = $this->createMock(ItemInterface::class);
1901
        $item
1902
            ->expects($this->once())
1903
            ->method('setChildrenAttribute')
1904
            ->with('class', 'nav navbar-nav');
1905
        $item
1906
            ->expects($this->once())
1907
            ->method('setExtra')
1908
            ->with('translation_domain', 'foo_bar_baz');
1909
1910
        $menuFactory = $this->createMock(FactoryInterface::class);
1911
        $menuFactory
1912
            ->expects($this->once())
1913
            ->method('createItem')
1914
            ->willReturn($item);
1915
1916
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1917
        $modelAdmin->setMenuFactory($menuFactory);
1918
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1919
1920
        $modelAdmin->getSideMenu('foo');
1921
    }
1922
1923
    /**
1924
     * @return array
1925
     */
1926
    public function provideGetSubject()
1927
    {
1928
        return [
1929
            [23],
1930
            ['azerty'],
1931
            ['4f69bbb5f14a13347f000092'],
1932
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1933
            ['123'.AdapterInterface::ID_SEPARATOR.'my_type'], // composite keys are supported
1934
        ];
1935
    }
1936
1937
    /**
1938
     * @dataProvider provideGetSubject
1939
     */
1940
    public function testGetSubjectFailed($id): void
1941
    {
1942
        $modelManager = $this->createMock(ModelManagerInterface::class);
1943
        $modelManager
1944
            ->expects($this->once())
1945
            ->method('find')
1946
            ->with('NewsBundle\Entity\Post', $id)
1947
            ->willReturn(null); // entity not found
1948
1949
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1950
        $admin->setModelManager($modelManager);
1951
1952
        $admin->setRequest(new Request(['id' => $id]));
1953
        $this->assertFalse($admin->hasSubject());
1954
    }
1955
1956
    /**
1957
     * @dataProvider provideGetSubject
1958
     */
1959
    public function testGetSubject($id): void
1960
    {
1961
        $model = new Post();
1962
1963
        $modelManager = $this->createMock(ModelManagerInterface::class);
1964
        $modelManager
1965
            ->expects($this->once())
1966
            ->method('find')
1967
            ->with('NewsBundle\Entity\Post', $id)
1968
            ->willReturn($model);
1969
1970
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1971
        $admin->setModelManager($modelManager);
1972
1973
        $admin->setRequest(new Request(['id' => $id]));
1974
        $this->assertTrue($admin->hasSubject());
1975
        $this->assertSame($model, $admin->getSubject());
1976
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
1977
    }
1978
1979
    public function testGetSubjectWithParentDescription(): void
1980
    {
1981
        $adminId = 1;
1982
1983
        $comment = new Comment();
1984
1985
        $modelManager = $this->createMock(ModelManagerInterface::class);
1986
        $modelManager
1987
            ->method('find')
1988
            ->with('NewsBundle\Entity\Comment', $adminId)
1989
            ->willReturn($comment);
1990
1991
        $request = new Request(['id' => $adminId]);
1992
1993
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1994
        $postAdmin->setRequest($request);
1995
1996
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1997
        $commentAdmin->setRequest($request);
1998
        $commentAdmin->setModelManager($modelManager);
1999
2000
        $this->assertTrue($commentAdmin->hasSubject());
2001
        $this->assertSame($comment, $commentAdmin->getSubject());
2002
2003
        $commentAdmin->setSubject(null);
2004
        $commentAdmin->setParentFieldDescription(new FieldDescription());
2005
2006
        $this->assertFalse($commentAdmin->hasSubject());
2007
    }
2008
2009
    /**
2010
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2011
     */
2012
    public function testGetActionButtonsList(): void
2013
    {
2014
        $expected = [
2015
            'create' => [
2016
                'template' => 'Foo.html.twig',
2017
            ],
2018
        ];
2019
2020
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2021
2022
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2023
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
2024
2025
        $admin->setTemplateRegistry($templateRegistry->reveal());
2026
2027
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2028
        $securityHandler
2029
            ->expects($this->once())
2030
            ->method('isGranted')
2031
            ->with($admin, 'CREATE', $admin)
2032
            ->willReturn(true);
2033
        $admin->setSecurityHandler($securityHandler);
2034
2035
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2036
        $routeGenerator
2037
            ->expects($this->once())
2038
            ->method('hasAdminRoute')
2039
            ->with($admin, 'create')
2040
            ->willReturn(true);
2041
        $admin->setRouteGenerator($routeGenerator);
2042
2043
        $this->assertSame($expected, $admin->getActionButtons('list', null));
2044
    }
2045
2046
    /**
2047
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2048
     */
2049
    public function testGetActionButtonsListCreateDisabled(): void
2050
    {
2051
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2052
2053
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2054
        $securityHandler
2055
            ->expects($this->once())
2056
            ->method('isGranted')
2057
            ->with($admin, 'CREATE', $admin)
2058
            ->willReturn(false);
2059
        $admin->setSecurityHandler($securityHandler);
2060
2061
        $this->assertSame([], $admin->getActionButtons('list', null));
2062
    }
2063
2064
    /**
2065
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
2066
     */
2067
    public function testGetBatchActions(): void
2068
    {
2069
        $expected = [
2070
            'delete' => [
2071
                'label' => 'action_delete',
2072
                'translation_domain' => 'SonataAdminBundle',
2073
                'ask_confirmation' => true, // by default always true
2074
            ],
2075
            'foo' => [
2076
                'label' => 'action_foo',
2077
                'translation_domain' => 'SonataAdminBundle',
2078
            ],
2079
            'bar' => [
2080
                'label' => 'batch.label_bar',
2081
                'translation_domain' => 'SonataAdminBundle',
2082
            ],
2083
            'baz' => [
2084
                'label' => 'action_baz',
2085
                'translation_domain' => 'AcmeAdminBundle',
2086
            ],
2087
        ];
2088
2089
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2090
2091
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
2092
        $labelTranslatorStrategy
2093
            ->method('getLabel')
2094
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2095
                return $context.'.'.$type.'_'.$label;
2096
            });
2097
2098
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2099
        $admin->setRouteBuilder($pathInfo);
2100
        $admin->setTranslationDomain('SonataAdminBundle');
2101
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
2102
2103
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2104
        $routeGenerator
2105
            ->expects($this->once())
2106
            ->method('hasAdminRoute')
2107
            ->with($admin, 'delete')
2108
            ->willReturn(true);
2109
        $admin->setRouteGenerator($routeGenerator);
2110
2111
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2112
        $securityHandler
2113
            ->method('isGranted')
2114
            ->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...
2115
                return $admin === $adminIn && 'DELETE' === $attributes;
2116
            });
2117
        $admin->setSecurityHandler($securityHandler);
2118
2119
        $this->assertSame($expected, $admin->getBatchActions());
2120
    }
2121
2122
    /**
2123
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2124
     */
2125
    public function testShowMosaicButton(): void
2126
    {
2127
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2128
        $listModes = $admin->getListModes();
2129
2130
        $admin->showMosaicButton(true);
2131
2132
        $this->assertSame($listModes, $admin->getListModes());
2133
    }
2134
2135
    /**
2136
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2137
     */
2138
    public function testShowMosaicButtonHideMosaic(): void
2139
    {
2140
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2141
        $listModes = $admin->getListModes();
2142
        $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...
2143
2144
        $admin->showMosaicButton(false);
2145
2146
        $this->assertSame($expected, $admin->getListModes());
2147
    }
2148
2149
    /**
2150
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2151
     * @dataProvider provideGetBaseRouteName
2152
     */
2153
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2154
    {
2155
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2156
2157
        $routeGenerator = new DefaultRouteGenerator(
2158
            $this->createMock(RouterInterface::class),
2159
            new RoutesCache($this->cacheTempFolder, true)
2160
        );
2161
2162
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
2163
        $admin->setRouteBuilder($pathInfo);
2164
        $admin->setRouteGenerator($routeGenerator);
2165
        $admin->initialize();
2166
2167
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2168
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2169
2170
        $admin->setTemplateRegistry($templateRegistry->reveal());
2171
2172
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2173
        $securityHandler
2174
            ->method('isGranted')
2175
            ->willReturnCallback(static function (AdminInterface $adminIn, string $attributes, $object = null) use ($admin): bool {
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2176
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2177
            });
2178
2179
        $admin->setSecurityHandler($securityHandler);
2180
2181
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2182
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2183
    }
2184
2185
    public function testDefaultFilters(): void
2186
    {
2187
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2188
2189
        $subjectId = uniqid();
2190
2191
        $request = $this->createMock(Request::class);
2192
        $query = $this->createMock(ParameterBag::class);
2193
        $query
2194
            ->method('get')
2195
            ->with($this->equalTo('filter'))
2196
            ->willReturn([
2197
                'a' => [
2198
                    'value' => 'b',
2199
                ],
2200
                'foo' => [
2201
                    'type' => '1',
2202
                    'value' => 'bar',
2203
                ],
2204
                'baz' => [
2205
                    'type' => '5',
2206
                    'value' => 'test',
2207
                ],
2208
            ]);
2209
        $request->query = $query;
2210
2211
        $request
2212
            ->method('get')
2213
            ->willReturn($subjectId);
2214
2215
        $admin->setRequest($request);
2216
2217
        $modelManager = $this->createMock(ModelManagerInterface::class);
2218
        $modelManager
2219
            ->method('getDefaultSortValues')
2220
            ->willReturn([]);
2221
2222
        $admin->setModelManager($modelManager);
2223
2224
        $this->assertSame([
2225
            '_page' => 1,
2226
            '_per_page' => 32,
2227
            'foo' => [
2228
                'type' => '1',
2229
                'value' => 'bar',
2230
            ],
2231
            'baz' => [
2232
                'type' => '5',
2233
                'value' => 'test',
2234
            ],
2235
            'a' => [
2236
                'value' => 'b',
2237
            ],
2238
        ], $admin->getFilterParameters());
2239
2240
        $this->assertTrue($admin->isDefaultFilter('foo'));
2241
        $this->assertFalse($admin->isDefaultFilter('bar'));
2242
        $this->assertFalse($admin->isDefaultFilter('a'));
2243
    }
2244
2245
    /**
2246
     * @group legacy
2247
     */
2248
    public function testDefaultBreadcrumbsBuilder(): void
2249
    {
2250
        $container = $this->createMock(ContainerInterface::class);
2251
        $container->expects($this->once())
2252
            ->method('getParameter')
2253
            ->with('sonata.admin.configuration.breadcrumbs')
2254
            ->willReturn([]);
2255
2256
        $pool = $this->getMockBuilder(Pool::class)
2257
            ->disableOriginalConstructor()
2258
            ->getMock();
2259
        $pool->expects($this->once())
2260
            ->method('getContainer')
2261
            ->willReturn($container);
2262
2263
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2264
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2265
        ], '', true, true, true, ['getConfigurationPool']);
2266
        $admin->expects($this->once())
2267
            ->method('getConfigurationPool')
2268
            ->willReturn($pool);
2269
2270
        $this->assertInstanceOf(BreadcrumbsBuilder::class, $admin->getBreadcrumbsBuilder());
2271
    }
2272
2273
    /**
2274
     * @group legacy
2275
     */
2276
    public function testBreadcrumbsBuilderSetter(): void
2277
    {
2278
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2279
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2280
        ]);
2281
        $this->assertSame($admin, $admin->setBreadcrumbsBuilder($builder = $this->createMock(
2282
            BreadcrumbsBuilderInterface::class
2283
        )));
2284
        $this->assertSame($builder, $admin->getBreadcrumbsBuilder());
2285
    }
2286
2287
    /**
2288
     * @group legacy
2289
     */
2290
    public function testGetBreadcrumbs(): void
2291
    {
2292
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2293
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2294
        ]);
2295
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2296
        $action = 'myaction';
2297
        $builder->getBreadcrumbs($admin, $action)->shouldBeCalled();
2298
        $admin->setBreadcrumbsBuilder($builder->reveal())->getBreadcrumbs($action);
2299
    }
2300
2301
    /**
2302
     * @group legacy
2303
     */
2304
    public function testBuildBreadcrumbs(): void
2305
    {
2306
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2307
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2308
        ]);
2309
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2310
        $action = 'myaction';
2311
        $menu = $this->createMock(ItemInterface::class);
2312
        $builder->buildBreadcrumbs($admin, $action, $menu)
2313
            ->shouldBeCalledTimes(1)
2314
            ->willReturn($menu);
2315
        $admin->setBreadcrumbsBuilder($builder->reveal());
2316
2317
        /* check the called is proxied only once */
2318
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2319
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2320
    }
2321
2322
    /**
2323
     * NEXT_MAJOR: remove this method.
2324
     *
2325
     * @group legacy
2326
     */
2327
    public function testCreateQueryLegacyCallWorks(): void
2328
    {
2329
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2330
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2331
        ]);
2332
        $query = $this->createMock(ProxyQueryInterface::class);
2333
        $modelManager = $this->createMock(ModelManagerInterface::class);
2334
        $modelManager->expects($this->once())
2335
            ->method('createQuery')
2336
            ->with('My\Class')
2337
            ->willReturn($query);
2338
2339
        $admin->setModelManager($modelManager);
2340
        $this->assertSame($query, $admin->createQuery('list'));
2341
    }
2342
2343
    public function testGetDataSourceIterator(): void
2344
    {
2345
        $datagrid = $this->createMock(DatagridInterface::class);
2346
        $datagrid->method('buildPager');
2347
2348
        $modelManager = $this->createMock(ModelManagerInterface::class);
2349
        $modelManager->method('getExportFields')->willReturn([
2350
            'field',
2351
            'foo',
2352
            'bar',
2353
        ]);
2354
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2355
            ->with($this->equalTo($datagrid), $this->equalTo([
2356
                'Feld' => 'field',
2357
                1 => 'foo',
2358
                2 => 'bar',
2359
            ]));
2360
2361
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2362
            ->disableOriginalConstructor()
2363
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2364
            ->getMockForAbstractClass();
2365
        $admin->method('getDatagrid')->willReturn($datagrid);
2366
        $admin->setModelManager($modelManager);
2367
2368
        $admin
2369
            ->method('getTranslationLabel')
2370
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2371
                return $context.'.'.$type.'_'.$label;
2372
            });
2373
        $admin
2374
            ->method('trans')
2375
            ->willReturnCallback(static function (string $label): string {
2376
                if ('export.label_field' === $label) {
2377
                    return 'Feld';
2378
                }
2379
2380
                return $label;
2381
            });
2382
2383
        $admin->getDataSourceIterator();
2384
    }
2385
2386
    public function testCircularChildAdmin(): void
2387
    {
2388
        $this->expectException(\RuntimeException::class);
2389
        $this->expectExceptionMessage(
2390
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2391
        );
2392
2393
        $postAdmin = new PostAdmin(
2394
            'sonata.post.admin.post',
2395
            'Application\Sonata\NewsBundle\Entity\Post',
2396
            'Sonata\NewsBundle\Controller\PostAdminController'
2397
        );
2398
        $commentAdmin = new CommentAdmin(
2399
            'sonata.post.admin.comment',
2400
            'Application\Sonata\NewsBundle\Entity\Comment',
2401
            'Sonata\NewsBundle\Controller\CommentAdminController'
2402
        );
2403
        $postAdmin->addChild($commentAdmin, 'post');
2404
        $commentAdmin->addChild($postAdmin, 'comment');
2405
    }
2406
2407
    public function testCircularChildAdminTripleLevel(): void
2408
    {
2409
        $this->expectException(\RuntimeException::class);
2410
        $this->expectExceptionMessage(
2411
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2412
        );
2413
2414
        $postAdmin = new PostAdmin(
2415
            'sonata.post.admin.post',
2416
            'Application\Sonata\NewsBundle\Entity\Post',
2417
            'Sonata\NewsBundle\Controller\PostAdminController'
2418
        );
2419
        $commentAdmin = new CommentAdmin(
2420
            'sonata.post.admin.comment',
2421
            'Application\Sonata\NewsBundle\Entity\Comment',
2422
            'Sonata\NewsBundle\Controller\CommentAdminController'
2423
        );
2424
        $commentVoteAdmin = new CommentVoteAdmin(
2425
            'sonata.post.admin.comment_vote',
2426
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2427
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2428
        );
2429
        $postAdmin->addChild($commentAdmin, 'post');
2430
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2431
        $commentVoteAdmin->addChild($postAdmin, 'post');
2432
    }
2433
2434
    public function testCircularChildAdminWithItself(): void
2435
    {
2436
        $this->expectException(\RuntimeException::class);
2437
        $this->expectExceptionMessage(
2438
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2439
        );
2440
2441
        $postAdmin = new PostAdmin(
2442
            'sonata.post.admin.post',
2443
            'Application\Sonata\NewsBundle\Entity\Post',
2444
            'Sonata\NewsBundle\Controller\PostAdminController'
2445
        );
2446
        $postAdmin->addChild($postAdmin);
2447
    }
2448
2449
    public function testGetRootAncestor(): void
2450
    {
2451
        $postAdmin = new PostAdmin(
2452
            'sonata.post.admin.post',
2453
            'Application\Sonata\NewsBundle\Entity\Post',
2454
            'Sonata\NewsBundle\Controller\PostAdminController'
2455
        );
2456
        $commentAdmin = new CommentAdmin(
2457
            'sonata.post.admin.comment',
2458
            'Application\Sonata\NewsBundle\Entity\Comment',
2459
            'Sonata\NewsBundle\Controller\CommentAdminController'
2460
        );
2461
        $commentVoteAdmin = new CommentVoteAdmin(
2462
            'sonata.post.admin.comment_vote',
2463
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2464
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2465
        );
2466
2467
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2468
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2469
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2470
2471
        $postAdmin->addChild($commentAdmin, 'post');
2472
2473
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2474
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2475
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2476
2477
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2478
2479
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2480
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2481
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2482
    }
2483
2484
    public function testGetChildDepth(): void
2485
    {
2486
        $postAdmin = new PostAdmin(
2487
            'sonata.post.admin.post',
2488
            'Application\Sonata\NewsBundle\Entity\Post',
2489
            'Sonata\NewsBundle\Controller\PostAdminController'
2490
        );
2491
        $commentAdmin = new CommentAdmin(
2492
            'sonata.post.admin.comment',
2493
            'Application\Sonata\NewsBundle\Entity\Comment',
2494
            'Sonata\NewsBundle\Controller\CommentAdminController'
2495
        );
2496
        $commentVoteAdmin = new CommentVoteAdmin(
2497
            'sonata.post.admin.comment_vote',
2498
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2499
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2500
        );
2501
2502
        $this->assertSame(0, $postAdmin->getChildDepth());
2503
        $this->assertSame(0, $commentAdmin->getChildDepth());
2504
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2505
2506
        $postAdmin->addChild($commentAdmin, 'post');
2507
2508
        $this->assertSame(0, $postAdmin->getChildDepth());
2509
        $this->assertSame(1, $commentAdmin->getChildDepth());
2510
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2511
2512
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2513
2514
        $this->assertSame(0, $postAdmin->getChildDepth());
2515
        $this->assertSame(1, $commentAdmin->getChildDepth());
2516
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2517
    }
2518
2519
    public function testGetCurrentLeafChildAdmin(): void
2520
    {
2521
        $postAdmin = new PostAdmin(
2522
            'sonata.post.admin.post',
2523
            'Application\Sonata\NewsBundle\Entity\Post',
2524
            'Sonata\NewsBundle\Controller\PostAdminController'
2525
        );
2526
        $commentAdmin = new CommentAdmin(
2527
            'sonata.post.admin.comment',
2528
            'Application\Sonata\NewsBundle\Entity\Comment',
2529
            'Sonata\NewsBundle\Controller\CommentAdminController'
2530
        );
2531
        $commentVoteAdmin = new CommentVoteAdmin(
2532
            'sonata.post.admin.comment_vote',
2533
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2534
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2535
        );
2536
2537
        $postAdmin->addChild($commentAdmin, 'post');
2538
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2539
2540
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2541
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2542
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2543
2544
        $commentAdmin->setCurrentChild(true);
2545
2546
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2547
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2548
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2549
2550
        $commentVoteAdmin->setCurrentChild(true);
2551
2552
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2553
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2554
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2555
    }
2556
2557
    public function testAdminWithoutControllerName(): void
2558
    {
2559
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', null);
2560
2561
        $this->assertNull($admin->getBaseControllerName());
2562
    }
2563
2564
    public function testAdminAvoidInifiniteLoop(): void
2565
    {
2566
        $this->expectNotToPerformAssertions();
2567
2568
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2569
2570
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2571
        $admin->setSubject(new \stdClass());
2572
2573
        $admin->setFormContractor(new FormContractor($formFactory));
2574
2575
        $admin->setShowBuilder(new ShowBuilder());
2576
2577
        $admin->setListBuilder(new ListBuilder());
2578
2579
        $pager = $this->createStub(PagerInterface::class);
2580
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2581
2582
        $validator = $this->createMock(ValidatorInterface::class);
2583
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2584
        $admin->setValidator($validator);
2585
2586
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2587
        $admin->setRouteGenerator($routeGenerator);
2588
2589
        $admin->getForm();
2590
        $admin->getShow();
2591
        $admin->getList();
2592
        $admin->getDatagrid();
2593
    }
2594
2595
    /**
2596
     * NEXT_MAJOR: Remove this test and its data provider.
2597
     *
2598
     * @group legacy
2599
     *
2600
     * @dataProvider getDeprecatedAbstractAdminConstructorArgs
2601
     *
2602
     * @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.
2603
     */
2604
    public function testDeprecatedAbstractAdminConstructorArgs($code, $class, $baseControllerName): void
2605
    {
2606
        new PostAdmin($code, $class, $baseControllerName);
2607
    }
2608
2609
    public function getDeprecatedAbstractAdminConstructorArgs(): iterable
2610
    {
2611
        yield from [
2612
            ['sonata.post.admin.post', null, null],
2613
            [null, null, null],
2614
            ['sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', false],
2615
            ['sonata.post.admin.post', false, false],
2616
            [false, false, false],
2617
            [true, true, true],
2618
            [new \stdClass(), new \stdClass(), new \stdClass()],
2619
            [0, 0, 0],
2620
            [1, 1, 1],
2621
        ];
2622
    }
2623
2624
    private function createTagAdmin(Post $post): TagAdmin
2625
    {
2626
        $postAdmin = $this->getMockBuilder(PostAdmin::class)
2627
            ->disableOriginalConstructor()
2628
            ->getMock();
2629
2630
        $postAdmin->method('getObject')->willReturn($post);
2631
2632
        $formBuilder = $this->createMock(FormBuilderInterface::class);
2633
        $formBuilder->method('getForm')->willReturn(null);
2634
2635
        $tagAdmin = $this->getMockBuilder(TagAdmin::class)
2636
            ->setConstructorArgs([
2637
                'admin.tag',
2638
                Tag::class,
2639
                'MyBundle\MyController',
2640
            ])
2641
            ->setMethods(['getFormBuilder'])
2642
            ->getMock();
2643
2644
        $tagAdmin->method('getFormBuilder')->willReturn($formBuilder);
2645
        $tagAdmin->setParent($postAdmin);
2646
2647
        $tag = new Tag();
2648
        $tagAdmin->setSubject($tag);
2649
2650
        $request = $this->createMock(Request::class);
2651
        $tagAdmin->setRequest($request);
2652
2653
        $configurationPool = $this->getMockBuilder(Pool::class)
2654
            ->disableOriginalConstructor()
2655
            ->getMock();
2656
2657
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
2658
2659
        $tagAdmin->setConfigurationPool($configurationPool);
2660
2661
        return $tagAdmin;
2662
    }
2663
}
2664