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

e()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading history...
1482
            }
1483
        };
1484
1485
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1486
1487
        $admin->setFilterPersister($filterPersister);
1488
        $this->assertTrue($admin->persistFilters());
1489
    }
1490
1491
    public function testGetRootCode(): void
1492
    {
1493
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1494
1495
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1496
1497
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1498
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1499
        $parentFieldDescription->expects($this->once())
1500
            ->method('getAdmin')
1501
            ->willReturn($parentAdmin);
1502
1503
        $this->assertFalse($admin->hasParentFieldDescription());
1504
        $admin->setParentFieldDescription($parentFieldDescription);
1505
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1506
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1507
    }
1508
1509
    public function testGetRoot(): void
1510
    {
1511
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1512
1513
        $this->assertSame($admin, $admin->getRoot());
1514
1515
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1516
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1517
        $parentFieldDescription->expects($this->once())
1518
            ->method('getAdmin')
1519
            ->willReturn($parentAdmin);
1520
1521
        $this->assertFalse($admin->hasParentFieldDescription());
1522
        $admin->setParentFieldDescription($parentFieldDescription);
1523
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1524
        $this->assertSame($parentAdmin, $admin->getRoot());
1525
    }
1526
1527
    public function testGetExportFields(): void
1528
    {
1529
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1530
1531
        $modelManager = $this->createMock(ModelManagerInterface::class);
1532
        $modelManager->expects($this->once())
1533
            ->method('getExportFields')
1534
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1535
            ->willReturn(['foo', 'bar']);
1536
1537
        $admin->setModelManager($modelManager);
1538
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1539
    }
1540
1541
    public function testGetPersistentParametersWithNoExtension(): void
1542
    {
1543
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1544
1545
        $this->assertEmpty($admin->getPersistentParameters());
1546
    }
1547
1548
    public function testGetPersistentParametersWithInvalidExtension(): void
1549
    {
1550
        $this->expectException(\RuntimeException::class);
1551
1552
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1553
1554
        $extension = $this->createMock(AdminExtensionInterface::class);
1555
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn(null);
1556
1557
        $admin->addExtension($extension);
1558
1559
        $admin->getPersistentParameters();
1560
    }
1561
1562
    public function testGetPersistentParametersWithValidExtension(): void
1563
    {
1564
        $expected = [
1565
            'context' => 'foobar',
1566
        ];
1567
1568
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1569
1570
        $extension = $this->createMock(AdminExtensionInterface::class);
1571
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1572
1573
        $admin->addExtension($extension);
1574
1575
        $this->assertSame($expected, $admin->getPersistentParameters());
1576
    }
1577
1578
    public function testGetFormWithCollectionParentValue(): void
1579
    {
1580
        $post = new Post();
1581
        $tagAdmin = $this->createTagAdmin($post);
1582
        $tag = $tagAdmin->getSubject();
1583
1584
        // Case of a doctrine collection
1585
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1586
        $this->assertCount(0, $tag->getPosts());
1587
1588
        $tag->addPost(new Post());
1589
1590
        $this->assertCount(1, $tag->getPosts());
1591
1592
        $tagAdmin->getForm();
1593
1594
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1595
        $this->assertCount(2, $tag->getPosts());
1596
        $this->assertContains($post, $tag->getPosts());
1597
    }
1598
1599
    public function testGetFormWithArrayParentValue(): void
1600
    {
1601
        $post = new Post();
1602
        $tagAdmin = $this->createTagAdmin($post);
1603
        $tag = $tagAdmin->getSubject();
1604
1605
        // Case of an array
1606
        $tag->setPosts([]);
1607
        $this->assertCount(0, $tag->getPosts());
1608
1609
        $tag->addPost(new Post());
1610
1611
        $this->assertCount(1, $tag->getPosts());
1612
1613
        $tagAdmin->getForm();
1614
1615
        $this->assertIsArray($tag->getPosts());
1616
        $this->assertCount(2, $tag->getPosts());
1617
        $this->assertContains($post, $tag->getPosts());
1618
    }
1619
1620
    public function testFormAddPostSubmitEventForPreValidation(): void
1621
    {
1622
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1623
        $object = new \stdClass();
1624
1625
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1626
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1627
1628
        $validator = $this->createMock(ValidatorInterface::class);
1629
        $validator
1630
                ->method('getMetadataFor')
1631
                ->willReturn($this->createMock(MemberMetadata::class));
1632
        $modelAdmin->setValidator($validator);
1633
1634
        $modelManager = $this->createMock(ModelManagerInterface::class);
1635
        $modelManager
1636
            ->method('getNewFieldDescriptionInstance')
1637
            ->willReturn(new FieldDescription());
1638
        $modelAdmin->setModelManager($modelManager);
1639
1640
        // a Admin class to test that preValidate is called
1641
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1642
        $testAdminPreValidate->expects($this->once())
1643
                ->method('preValidate')
1644
                ->with($this->identicalTo($object));
1645
1646
        $event = $this->createMock(FormEvent::class);
1647
        $event
1648
                ->method('getData')
1649
                ->willReturn($object);
1650
1651
        $formBuild = $this->createMock(FormBuilder::class);
1652
        $formBuild->expects($this->once())
1653
                ->method('addEventListener')
1654
                ->with(
1655
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1656
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1657
                        if (\is_callable($callback)) {
1658
                            $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...
1659
                            $closure($event);
1660
1661
                            return true;
1662
                        }
1663
1664
                        return false;
1665
                    }),
1666
                    $this->greaterThan(0)
1667
                );
1668
1669
        $formContractor = $this->createMock(FormContractorInterface::class);
1670
        $formContractor
1671
                ->method('getDefaultOptions')
1672
                ->willReturn([]);
1673
        $formContractor
1674
                ->method('getFormBuilder')
1675
                ->willReturn($formBuild);
1676
1677
        $modelAdmin->setFormContractor($formContractor);
1678
        $modelAdmin->setSubject($object);
1679
        $modelAdmin->defineFormBuilder($formBuild);
1680
        $modelAdmin->getForm();
1681
    }
1682
1683
    public function testRemoveFieldFromFormGroup(): void
1684
    {
1685
        $formGroups = [
1686
            'foobar' => [
1687
                'fields' => [
1688
                    'foo' => 'foo',
1689
                    'bar' => 'bar',
1690
                ],
1691
            ],
1692
        ];
1693
1694
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1695
        $admin->setFormGroups($formGroups);
1696
1697
        $admin->removeFieldFromFormGroup('foo');
1698
        $this->assertSame($admin->getFormGroups(), [
1699
            'foobar' => [
1700
                'fields' => [
1701
                    'bar' => 'bar',
1702
                ],
1703
            ],
1704
        ]);
1705
1706
        $admin->removeFieldFromFormGroup('bar');
1707
        $this->assertSame($admin->getFormGroups(), []);
1708
    }
1709
1710
    public function testGetFilterParameters(): void
1711
    {
1712
        $authorId = uniqid();
1713
1714
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1715
1716
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1717
        $commentAdmin->setParentAssociationMapping('post.author');
1718
        $commentAdmin->setParent($postAdmin);
1719
1720
        $request = $this->createMock(Request::class);
1721
        $query = $this->createMock(ParameterBag::class);
1722
        $query
1723
            ->method('get')
1724
            ->willReturn([
1725
                'filter' => [
1726
                    '_page' => '1',
1727
                    '_per_page' => '32',
1728
                ],
1729
            ]);
1730
1731
        $request->query = $query;
1732
        $request
1733
            ->method('get')
1734
            ->willReturn($authorId);
1735
1736
        $commentAdmin->setRequest($request);
1737
1738
        $modelManager = $this->createMock(ModelManagerInterface::class);
1739
        $modelManager
1740
            ->method('getDefaultSortValues')
1741
            ->willReturn([]);
1742
1743
        $commentAdmin->setModelManager($modelManager);
1744
1745
        $parameters = $commentAdmin->getFilterParameters();
1746
1747
        $this->assertTrue(isset($parameters['post__author']));
1748
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1749
    }
1750
1751
    public function testGetFilterFieldDescription(): void
1752
    {
1753
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1754
1755
        $fooFieldDescription = new FieldDescription();
1756
        $barFieldDescription = new FieldDescription();
1757
        $bazFieldDescription = new FieldDescription();
1758
1759
        $modelManager = $this->createMock(ModelManagerInterface::class);
1760
        $modelManager->expects($this->exactly(3))
1761
            ->method('getNewFieldDescriptionInstance')
1762
            ->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...
1763
                switch ($name) {
1764
                    case 'foo':
1765
                        $fieldDescription = $fooFieldDescription;
1766
1767
                        break;
1768
1769
                    case 'bar':
1770
                        $fieldDescription = $barFieldDescription;
1771
1772
                        break;
1773
1774
                    case 'baz':
1775
                        $fieldDescription = $bazFieldDescription;
1776
1777
                        break;
1778
1779
                    default:
1780
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1781
                        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...
1782
                }
1783
1784
                $fieldDescription->setName($name);
1785
1786
                return $fieldDescription;
1787
            });
1788
1789
        $modelAdmin->setModelManager($modelManager);
1790
1791
        $pager = $this->createMock(PagerInterface::class);
1792
1793
        $datagrid = $this->createMock(DatagridInterface::class);
1794
        $datagrid->expects($this->once())
1795
            ->method('getPager')
1796
            ->willReturn($pager);
1797
1798
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1799
        $datagridBuilder->expects($this->once())
1800
            ->method('getBaseDatagrid')
1801
            ->with($this->identicalTo($modelAdmin), [])
1802
            ->willReturn($datagrid);
1803
1804
        $datagridBuilder->expects($this->exactly(3))
1805
            ->method('addFilter')
1806
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1807
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1808
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1809
            });
1810
1811
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1812
1813
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1814
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1815
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1816
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1817
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1818
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1819
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1820
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1821
    }
1822
1823
    public function testGetSubjectNoRequest(): void
1824
    {
1825
        $modelManager = $this->createMock(ModelManagerInterface::class);
1826
        $modelManager
1827
            ->expects($this->never())
1828
            ->method('find');
1829
1830
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1831
        $admin->setModelManager($modelManager);
1832
1833
        $this->assertFalse($admin->hasSubject());
1834
    }
1835
1836
    public function testGetSideMenu(): void
1837
    {
1838
        $item = $this->createMock(ItemInterface::class);
1839
        $item
1840
            ->expects($this->once())
1841
            ->method('setChildrenAttribute')
1842
            ->with('class', 'nav navbar-nav');
1843
        $item
1844
            ->expects($this->once())
1845
            ->method('setExtra')
1846
            ->with('translation_domain', 'foo_bar_baz');
1847
1848
        $menuFactory = $this->createMock(FactoryInterface::class);
1849
        $menuFactory
1850
            ->expects($this->once())
1851
            ->method('createItem')
1852
            ->willReturn($item);
1853
1854
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1855
        $modelAdmin->setMenuFactory($menuFactory);
1856
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1857
1858
        $modelAdmin->getSideMenu('foo');
1859
    }
1860
1861
    /**
1862
     * @return array
1863
     */
1864
    public function provideGetSubject()
1865
    {
1866
        return [
1867
            [23],
1868
            ['azerty'],
1869
            ['4f69bbb5f14a13347f000092'],
1870
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1871
            ['123'.AdapterInterface::ID_SEPARATOR.'my_type'], // composite keys are supported
1872
        ];
1873
    }
1874
1875
    /**
1876
     * @dataProvider provideGetSubject
1877
     */
1878
    public function testGetSubjectFailed($id): void
1879
    {
1880
        $modelManager = $this->createMock(ModelManagerInterface::class);
1881
        $modelManager
1882
            ->expects($this->once())
1883
            ->method('find')
1884
            ->with('NewsBundle\Entity\Post', $id)
1885
            ->willReturn(null); // entity not found
1886
1887
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1888
        $admin->setModelManager($modelManager);
1889
1890
        $admin->setRequest(new Request(['id' => $id]));
1891
        $this->assertFalse($admin->hasSubject());
1892
    }
1893
1894
    /**
1895
     * @dataProvider provideGetSubject
1896
     */
1897
    public function testGetSubject($id): void
1898
    {
1899
        $model = new Post();
1900
1901
        $modelManager = $this->createMock(ModelManagerInterface::class);
1902
        $modelManager
1903
            ->expects($this->once())
1904
            ->method('find')
1905
            ->with('NewsBundle\Entity\Post', $id)
1906
            ->willReturn($model);
1907
1908
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1909
        $admin->setModelManager($modelManager);
1910
1911
        $admin->setRequest(new Request(['id' => $id]));
1912
        $this->assertTrue($admin->hasSubject());
1913
        $this->assertSame($model, $admin->getSubject());
1914
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
1915
    }
1916
1917
    public function testGetSubjectWithParentDescription(): void
1918
    {
1919
        $adminId = 1;
1920
1921
        $comment = new Comment();
1922
1923
        $modelManager = $this->createMock(ModelManagerInterface::class);
1924
        $modelManager
1925
            ->method('find')
1926
            ->with('NewsBundle\Entity\Comment', $adminId)
1927
            ->willReturn($comment);
1928
1929
        $request = new Request(['id' => $adminId]);
1930
1931
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1932
        $postAdmin->setRequest($request);
1933
1934
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1935
        $commentAdmin->setRequest($request);
1936
        $commentAdmin->setModelManager($modelManager);
1937
1938
        $this->assertTrue($commentAdmin->hasSubject());
1939
        $this->assertSame($comment, $commentAdmin->getSubject());
1940
1941
        $commentAdmin->setSubject(null);
1942
        $commentAdmin->setParentFieldDescription(new FieldDescription());
1943
1944
        $this->assertFalse($commentAdmin->hasSubject());
1945
    }
1946
1947
    /**
1948
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1949
     */
1950
    public function testGetActionButtonsList(): void
1951
    {
1952
        $expected = [
1953
            'create' => [
1954
                'template' => 'Foo.html.twig',
1955
            ],
1956
        ];
1957
1958
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1959
1960
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1961
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
1962
1963
        $admin->setTemplateRegistry($templateRegistry->reveal());
1964
1965
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1966
        $securityHandler
1967
            ->expects($this->once())
1968
            ->method('isGranted')
1969
            ->with($admin, 'CREATE', $admin)
1970
            ->willReturn(true);
1971
        $admin->setSecurityHandler($securityHandler);
1972
1973
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1974
        $routeGenerator
1975
            ->expects($this->once())
1976
            ->method('hasAdminRoute')
1977
            ->with($admin, 'create')
1978
            ->willReturn(true);
1979
        $admin->setRouteGenerator($routeGenerator);
1980
1981
        $this->assertSame($expected, $admin->getActionButtons('list', null));
1982
    }
1983
1984
    /**
1985
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1986
     */
1987
    public function testGetActionButtonsListCreateDisabled(): void
1988
    {
1989
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1990
1991
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1992
        $securityHandler
1993
            ->expects($this->once())
1994
            ->method('isGranted')
1995
            ->with($admin, 'CREATE', $admin)
1996
            ->willReturn(false);
1997
        $admin->setSecurityHandler($securityHandler);
1998
1999
        $this->assertSame([], $admin->getActionButtons('list', null));
2000
    }
2001
2002
    /**
2003
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
2004
     */
2005
    public function testGetBatchActions(): void
2006
    {
2007
        $expected = [
2008
            'delete' => [
2009
                'label' => 'action_delete',
2010
                'translation_domain' => 'SonataAdminBundle',
2011
                'ask_confirmation' => true, // by default always true
2012
            ],
2013
            'foo' => [
2014
                'label' => 'action_foo',
2015
                'translation_domain' => 'SonataAdminBundle',
2016
            ],
2017
            'bar' => [
2018
                'label' => 'batch.label_bar',
2019
                'translation_domain' => 'SonataAdminBundle',
2020
            ],
2021
            'baz' => [
2022
                'label' => 'action_baz',
2023
                'translation_domain' => 'AcmeAdminBundle',
2024
            ],
2025
        ];
2026
2027
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2028
2029
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
2030
        $labelTranslatorStrategy
2031
            ->method('getLabel')
2032
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2033
                return $context.'.'.$type.'_'.$label;
2034
            });
2035
2036
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2037
        $admin->setRouteBuilder($pathInfo);
2038
        $admin->setTranslationDomain('SonataAdminBundle');
2039
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
2040
2041
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2042
        $routeGenerator
2043
            ->expects($this->once())
2044
            ->method('hasAdminRoute')
2045
            ->with($admin, 'delete')
2046
            ->willReturn(true);
2047
        $admin->setRouteGenerator($routeGenerator);
2048
2049
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2050
        $securityHandler
2051
            ->method('isGranted')
2052
            ->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...
2053
                return $admin === $adminIn && 'DELETE' === $attributes;
2054
            });
2055
        $admin->setSecurityHandler($securityHandler);
2056
2057
        $this->assertSame($expected, $admin->getBatchActions());
2058
    }
2059
2060
    /**
2061
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2062
     */
2063
    public function testShowMosaicButton(): void
2064
    {
2065
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2066
        $listModes = $admin->getListModes();
2067
2068
        $admin->showMosaicButton(true);
2069
2070
        $this->assertSame($listModes, $admin->getListModes());
2071
    }
2072
2073
    /**
2074
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2075
     */
2076
    public function testShowMosaicButtonHideMosaic(): void
2077
    {
2078
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2079
        $listModes = $admin->getListModes();
2080
        $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...
2081
2082
        $admin->showMosaicButton(false);
2083
2084
        $this->assertSame($expected, $admin->getListModes());
2085
    }
2086
2087
    /**
2088
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2089
     * @dataProvider provideGetBaseRouteName
2090
     */
2091
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2092
    {
2093
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2094
2095
        $routeGenerator = new DefaultRouteGenerator(
2096
            $this->createMock(RouterInterface::class),
2097
            new RoutesCache($this->cacheTempFolder, true)
2098
        );
2099
2100
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
2101
        $admin->setRouteBuilder($pathInfo);
2102
        $admin->setRouteGenerator($routeGenerator);
2103
        $admin->initialize();
2104
2105
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2106
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2107
2108
        $admin->setTemplateRegistry($templateRegistry->reveal());
2109
2110
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2111
        $securityHandler
2112
            ->method('isGranted')
2113
            ->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...
2114
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2115
            });
2116
2117
        $admin->setSecurityHandler($securityHandler);
2118
2119
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2120
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2121
    }
2122
2123
    public function testDefaultFilters(): void
2124
    {
2125
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2126
2127
        $subjectId = uniqid();
2128
2129
        $request = $this->createMock(Request::class);
2130
        $query = $this->createMock(ParameterBag::class);
2131
        $query
2132
            ->method('get')
2133
            ->with($this->equalTo('filter'))
2134
            ->willReturn([
2135
                'a' => [
2136
                    'value' => 'b',
2137
                ],
2138
                'foo' => [
2139
                    'type' => '1',
2140
                    'value' => 'bar',
2141
                ],
2142
                'baz' => [
2143
                    'type' => '5',
2144
                    'value' => 'test',
2145
                ],
2146
            ]);
2147
        $request->query = $query;
2148
2149
        $request
2150
            ->method('get')
2151
            ->willReturn($subjectId);
2152
2153
        $admin->setRequest($request);
2154
2155
        $modelManager = $this->createMock(ModelManagerInterface::class);
2156
        $modelManager
2157
            ->method('getDefaultSortValues')
2158
            ->willReturn([]);
2159
2160
        $admin->setModelManager($modelManager);
2161
2162
        $this->assertSame([
2163
            '_page' => 1,
2164
            '_per_page' => 32,
2165
            'foo' => [
2166
                'type' => '1',
2167
                'value' => 'bar',
2168
            ],
2169
            'baz' => [
2170
                'type' => '5',
2171
                'value' => 'test',
2172
            ],
2173
            'a' => [
2174
                'value' => 'b',
2175
            ],
2176
        ], $admin->getFilterParameters());
2177
2178
        $this->assertTrue($admin->isDefaultFilter('foo'));
2179
        $this->assertFalse($admin->isDefaultFilter('bar'));
2180
        $this->assertFalse($admin->isDefaultFilter('a'));
2181
    }
2182
2183
    /**
2184
     * @group legacy
2185
     */
2186
    public function testDefaultBreadcrumbsBuilder(): void
2187
    {
2188
        $container = $this->createMock(ContainerInterface::class);
2189
        $container->expects($this->once())
2190
            ->method('getParameter')
2191
            ->with('sonata.admin.configuration.breadcrumbs')
2192
            ->willReturn([]);
2193
2194
        $pool = $this->getMockBuilder(Pool::class)
2195
            ->disableOriginalConstructor()
2196
            ->getMock();
2197
        $pool->expects($this->once())
2198
            ->method('getContainer')
2199
            ->willReturn($container);
2200
2201
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2202
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2203
        ], '', true, true, true, ['getConfigurationPool']);
2204
        $admin->expects($this->once())
2205
            ->method('getConfigurationPool')
2206
            ->willReturn($pool);
2207
2208
        $this->assertInstanceOf(BreadcrumbsBuilder::class, $admin->getBreadcrumbsBuilder());
2209
    }
2210
2211
    /**
2212
     * @group legacy
2213
     */
2214
    public function testBreadcrumbsBuilderSetter(): void
2215
    {
2216
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2217
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2218
        ]);
2219
        $this->assertSame($admin, $admin->setBreadcrumbsBuilder($builder = $this->createMock(
2220
            BreadcrumbsBuilderInterface::class
2221
        )));
2222
        $this->assertSame($builder, $admin->getBreadcrumbsBuilder());
2223
    }
2224
2225
    /**
2226
     * @group legacy
2227
     */
2228
    public function testGetBreadcrumbs(): void
2229
    {
2230
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2231
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2232
        ]);
2233
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2234
        $action = 'myaction';
2235
        $builder->getBreadcrumbs($admin, $action)->shouldBeCalled();
2236
        $admin->setBreadcrumbsBuilder($builder->reveal())->getBreadcrumbs($action);
2237
    }
2238
2239
    /**
2240
     * @group legacy
2241
     */
2242
    public function testBuildBreadcrumbs(): void
2243
    {
2244
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2245
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2246
        ]);
2247
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2248
        $action = 'myaction';
2249
        $menu = $this->createMock(ItemInterface::class);
2250
        $builder->buildBreadcrumbs($admin, $action, $menu)
2251
            ->shouldBeCalledTimes(1)
2252
            ->willReturn($menu);
2253
        $admin->setBreadcrumbsBuilder($builder->reveal());
2254
2255
        /* check the called is proxied only once */
2256
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2257
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2258
    }
2259
2260
    /**
2261
     * NEXT_MAJOR: remove this method.
2262
     *
2263
     * @group legacy
2264
     */
2265
    public function testCreateQueryLegacyCallWorks(): void
2266
    {
2267
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2268
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2269
        ]);
2270
        $query = $this->createMock(ProxyQueryInterface::class);
2271
        $modelManager = $this->createMock(ModelManagerInterface::class);
2272
        $modelManager->expects($this->once())
2273
            ->method('createQuery')
2274
            ->with('My\Class')
2275
            ->willReturn($query);
2276
2277
        $admin->setModelManager($modelManager);
2278
        $this->assertSame($query, $admin->createQuery('list'));
2279
    }
2280
2281
    public function testGetDataSourceIterator(): void
2282
    {
2283
        $datagrid = $this->createMock(DatagridInterface::class);
2284
        $datagrid->method('buildPager');
2285
2286
        $modelManager = $this->createMock(ModelManagerInterface::class);
2287
        $modelManager->method('getExportFields')->willReturn([
2288
            'field',
2289
            'foo',
2290
            'bar',
2291
        ]);
2292
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2293
            ->with($this->equalTo($datagrid), $this->equalTo([
2294
                'Feld' => 'field',
2295
                1 => 'foo',
2296
                2 => 'bar',
2297
            ]));
2298
2299
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2300
            ->disableOriginalConstructor()
2301
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2302
            ->getMockForAbstractClass();
2303
        $admin->method('getDatagrid')->willReturn($datagrid);
2304
        $admin->setModelManager($modelManager);
2305
2306
        $admin
2307
            ->method('getTranslationLabel')
2308
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2309
                return $context.'.'.$type.'_'.$label;
2310
            });
2311
        $admin
2312
            ->method('trans')
2313
            ->willReturnCallback(static function (string $label): string {
2314
                if ('export.label_field' === $label) {
2315
                    return 'Feld';
2316
                }
2317
2318
                return $label;
2319
            });
2320
2321
        $admin->getDataSourceIterator();
2322
    }
2323
2324
    public function testCircularChildAdmin(): void
2325
    {
2326
        $this->expectException(\RuntimeException::class);
2327
        $this->expectExceptionMessage(
2328
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2329
        );
2330
2331
        $postAdmin = new PostAdmin(
2332
            'sonata.post.admin.post',
2333
            'Application\Sonata\NewsBundle\Entity\Post',
2334
            'Sonata\NewsBundle\Controller\PostAdminController'
2335
        );
2336
        $commentAdmin = new CommentAdmin(
2337
            'sonata.post.admin.comment',
2338
            'Application\Sonata\NewsBundle\Entity\Comment',
2339
            'Sonata\NewsBundle\Controller\CommentAdminController'
2340
        );
2341
        $postAdmin->addChild($commentAdmin, 'post');
2342
        $commentAdmin->addChild($postAdmin, 'comment');
2343
    }
2344
2345
    public function testCircularChildAdminTripleLevel(): void
2346
    {
2347
        $this->expectException(\RuntimeException::class);
2348
        $this->expectExceptionMessage(
2349
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2350
        );
2351
2352
        $postAdmin = new PostAdmin(
2353
            'sonata.post.admin.post',
2354
            'Application\Sonata\NewsBundle\Entity\Post',
2355
            'Sonata\NewsBundle\Controller\PostAdminController'
2356
        );
2357
        $commentAdmin = new CommentAdmin(
2358
            'sonata.post.admin.comment',
2359
            'Application\Sonata\NewsBundle\Entity\Comment',
2360
            'Sonata\NewsBundle\Controller\CommentAdminController'
2361
        );
2362
        $commentVoteAdmin = new CommentVoteAdmin(
2363
            'sonata.post.admin.comment_vote',
2364
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2365
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2366
        );
2367
        $postAdmin->addChild($commentAdmin, 'post');
2368
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2369
        $commentVoteAdmin->addChild($postAdmin, 'post');
2370
    }
2371
2372
    public function testCircularChildAdminWithItself(): void
2373
    {
2374
        $this->expectException(\RuntimeException::class);
2375
        $this->expectExceptionMessage(
2376
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2377
        );
2378
2379
        $postAdmin = new PostAdmin(
2380
            'sonata.post.admin.post',
2381
            'Application\Sonata\NewsBundle\Entity\Post',
2382
            'Sonata\NewsBundle\Controller\PostAdminController'
2383
        );
2384
        $postAdmin->addChild($postAdmin);
2385
    }
2386
2387
    public function testGetRootAncestor(): void
2388
    {
2389
        $postAdmin = new PostAdmin(
2390
            'sonata.post.admin.post',
2391
            'Application\Sonata\NewsBundle\Entity\Post',
2392
            'Sonata\NewsBundle\Controller\PostAdminController'
2393
        );
2394
        $commentAdmin = new CommentAdmin(
2395
            'sonata.post.admin.comment',
2396
            'Application\Sonata\NewsBundle\Entity\Comment',
2397
            'Sonata\NewsBundle\Controller\CommentAdminController'
2398
        );
2399
        $commentVoteAdmin = new CommentVoteAdmin(
2400
            'sonata.post.admin.comment_vote',
2401
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2402
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2403
        );
2404
2405
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2406
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2407
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2408
2409
        $postAdmin->addChild($commentAdmin, 'post');
2410
2411
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2412
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2413
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2414
2415
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2416
2417
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2418
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2419
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2420
    }
2421
2422
    public function testGetChildDepth(): void
2423
    {
2424
        $postAdmin = new PostAdmin(
2425
            'sonata.post.admin.post',
2426
            'Application\Sonata\NewsBundle\Entity\Post',
2427
            'Sonata\NewsBundle\Controller\PostAdminController'
2428
        );
2429
        $commentAdmin = new CommentAdmin(
2430
            'sonata.post.admin.comment',
2431
            'Application\Sonata\NewsBundle\Entity\Comment',
2432
            'Sonata\NewsBundle\Controller\CommentAdminController'
2433
        );
2434
        $commentVoteAdmin = new CommentVoteAdmin(
2435
            'sonata.post.admin.comment_vote',
2436
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2437
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2438
        );
2439
2440
        $this->assertSame(0, $postAdmin->getChildDepth());
2441
        $this->assertSame(0, $commentAdmin->getChildDepth());
2442
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2443
2444
        $postAdmin->addChild($commentAdmin, 'post');
2445
2446
        $this->assertSame(0, $postAdmin->getChildDepth());
2447
        $this->assertSame(1, $commentAdmin->getChildDepth());
2448
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2449
2450
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2451
2452
        $this->assertSame(0, $postAdmin->getChildDepth());
2453
        $this->assertSame(1, $commentAdmin->getChildDepth());
2454
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2455
    }
2456
2457
    public function testGetCurrentLeafChildAdmin(): void
2458
    {
2459
        $postAdmin = new PostAdmin(
2460
            'sonata.post.admin.post',
2461
            'Application\Sonata\NewsBundle\Entity\Post',
2462
            'Sonata\NewsBundle\Controller\PostAdminController'
2463
        );
2464
        $commentAdmin = new CommentAdmin(
2465
            'sonata.post.admin.comment',
2466
            'Application\Sonata\NewsBundle\Entity\Comment',
2467
            'Sonata\NewsBundle\Controller\CommentAdminController'
2468
        );
2469
        $commentVoteAdmin = new CommentVoteAdmin(
2470
            'sonata.post.admin.comment_vote',
2471
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2472
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2473
        );
2474
2475
        $postAdmin->addChild($commentAdmin, 'post');
2476
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2477
2478
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2479
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2480
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2481
2482
        $commentAdmin->setCurrentChild(true);
2483
2484
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2485
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2486
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2487
2488
        $commentVoteAdmin->setCurrentChild(true);
2489
2490
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2491
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2492
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2493
    }
2494
2495
    public function testAdminWithoutControllerName(): void
2496
    {
2497
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', null);
2498
2499
        $this->assertNull($admin->getBaseControllerName());
2500
    }
2501
2502
    public function testAdminAvoidInifiniteLoop(): void
2503
    {
2504
        $this->expectNotToPerformAssertions();
2505
2506
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2507
2508
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2509
        $admin->setSubject(new \stdClass());
2510
2511
        $admin->setFormContractor(new FormContractor($formFactory));
2512
2513
        $admin->setShowBuilder(new ShowBuilder());
2514
2515
        $admin->setListBuilder(new ListBuilder());
2516
2517
        $pager = $this->createStub(PagerInterface::class);
2518
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2519
2520
        $validator = $this->createMock(ValidatorInterface::class);
2521
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2522
        $admin->setValidator($validator);
2523
2524
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2525
        $admin->setRouteGenerator($routeGenerator);
2526
2527
        $admin->getForm();
2528
        $admin->getShow();
2529
        $admin->getList();
2530
        $admin->getDatagrid();
2531
    }
2532
2533
    /**
2534
     * NEXT_MAJOR: Remove this test and its data provider.
2535
     *
2536
     * @group legacy
2537
     *
2538
     * @dataProvider getDeprecatedAbstractAdminConstructorArgs
2539
     *
2540
     * @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.
2541
     */
2542
    public function testDeprecatedAbstractAdminConstructorArgs($code, $class, $baseControllerName): void
2543
    {
2544
        new PostAdmin($code, $class, $baseControllerName);
2545
    }
2546
2547
    public function getDeprecatedAbstractAdminConstructorArgs(): iterable
2548
    {
2549
        yield from [
2550
            ['sonata.post.admin.post', null, null],
2551
            [null, null, null],
2552
            ['sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', false],
2553
            ['sonata.post.admin.post', false, false],
2554
            [false, false, false],
2555
            [true, true, true],
2556
            [new \stdClass(), new \stdClass(), new \stdClass()],
2557
            [0, 0, 0],
2558
            [1, 1, 1],
2559
        ];
2560
    }
2561
2562
    private function createTagAdmin(Post $post): TagAdmin
2563
    {
2564
        $postAdmin = $this->getMockBuilder(PostAdmin::class)
2565
            ->disableOriginalConstructor()
2566
            ->getMock();
2567
2568
        $postAdmin->method('getObject')->willReturn($post);
2569
2570
        $formBuilder = $this->createMock(FormBuilderInterface::class);
2571
        $formBuilder->method('getForm')->willReturn(null);
2572
2573
        $parentField = $this->createMock(FieldDescriptionInterface::class);
2574
        $parentField->method('getAdmin')->willReturn($postAdmin);
2575
        $parentField->method('getParentAssociationMappings')->willReturn([]);
2576
        $parentField->method('getAssociationMapping')->willReturn(['fieldName' => 'tag']);
2577
2578
        $tagAdmin = $this->getMockBuilder(TagAdmin::class)
2579
            ->setConstructorArgs([
2580
                'admin.tag',
2581
                Tag::class,
2582
                'MyBundle\MyController',
2583
            ])
2584
            ->setMethods(['getFormBuilder'])
2585
            ->getMock();
2586
2587
        $tagAdmin->method('getFormBuilder')->willReturn($formBuilder);
2588
        $tagAdmin->setParentFieldDescription($parentField);
2589
2590
        $tag = new Tag();
2591
        $tagAdmin->setSubject($tag);
2592
2593
        $request = $this->createMock(Request::class);
2594
        $tagAdmin->setRequest($request);
2595
2596
        $configurationPool = $this->getMockBuilder(Pool::class)
2597
            ->disableOriginalConstructor()
2598
            ->getMock();
2599
2600
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
2601
2602
        $tagAdmin->setConfigurationPool($configurationPool);
2603
2604
        return $tagAdmin;
2605
    }
2606
}
2607