Completed
Push — master ( 3fd2dd...aba624 )
by Grégoire
04:19
created

tests/Admin/AdminTest.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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