Completed
Push — 3.x ( b75183...b1c847 )
by Oskar
04:45
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\BreadcrumbsBuilder;
25
use Sonata\AdminBundle\Admin\BreadcrumbsBuilderInterface;
26
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
27
use Sonata\AdminBundle\Admin\Pool;
28
use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
29
use Sonata\AdminBundle\Builder\FormContractorInterface;
30
use Sonata\AdminBundle\Builder\ListBuilderInterface;
31
use Sonata\AdminBundle\Builder\RouteBuilderInterface;
32
use Sonata\AdminBundle\Builder\ShowBuilderInterface;
33
use Sonata\AdminBundle\Datagrid\DatagridInterface;
34
use Sonata\AdminBundle\Datagrid\PagerInterface;
35
use Sonata\AdminBundle\Model\AuditManagerInterface;
36
use Sonata\AdminBundle\Model\ModelManagerInterface;
37
use Sonata\AdminBundle\Route\DefaultRouteGenerator;
38
use Sonata\AdminBundle\Route\PathInfoBuilder;
39
use Sonata\AdminBundle\Route\RouteGeneratorInterface;
40
use Sonata\AdminBundle\Route\RoutesCache;
41
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
42
use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface;
43
use Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface;
44
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentAdmin;
45
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentVoteAdmin;
46
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentWithCustomRouteAdmin;
47
use Sonata\AdminBundle\Tests\Fixtures\Admin\FieldDescription;
48
use Sonata\AdminBundle\Tests\Fixtures\Admin\FilteredAdmin;
49
use Sonata\AdminBundle\Tests\Fixtures\Admin\ModelAdmin;
50
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin;
51
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostWithCustomRouteAdmin;
52
use Sonata\AdminBundle\Tests\Fixtures\Admin\TagAdmin;
53
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\BlogPost;
54
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment;
55
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Post;
56
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Tag;
57
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
58
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToStringNull;
59
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
60
use Sonata\Doctrine\Adapter\AdapterInterface;
61
use Symfony\Component\DependencyInjection\Container;
62
use Symfony\Component\DependencyInjection\ContainerInterface;
63
use Symfony\Component\Form\FormBuilder;
64
use Symfony\Component\Form\FormBuilderInterface;
65
use Symfony\Component\Form\FormEvent;
66
use Symfony\Component\Form\FormEvents;
67
use Symfony\Component\HttpFoundation\ParameterBag;
68
use Symfony\Component\HttpFoundation\Request;
69
use Symfony\Component\PropertyAccess\PropertyAccess;
70
use Symfony\Component\Routing\RouterInterface;
71
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
72
use Symfony\Component\Translation\TranslatorInterface;
73
use Symfony\Component\Validator\Mapping\MemberMetadata;
74
use Symfony\Component\Validator\Validator\ValidatorInterface;
75
76
class AdminTest extends TestCase
77
{
78
    protected $cacheTempFolder;
79
80
    public function setUp(): void
81
    {
82
        $this->cacheTempFolder = sys_get_temp_dir().'/sonata_test_route';
83
84
        exec('rm -rf '.$this->cacheTempFolder);
85
    }
86
87
    /**
88
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::__construct
89
     */
90
    public function testConstructor(): void
91
    {
92
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
93
        $baseControllerName = 'SonataNewsBundle:PostAdmin';
94
95
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
96
        $this->assertInstanceOf(AbstractAdmin::class, $admin);
97
        $this->assertSame($class, $admin->getClass());
98
        $this->assertSame($baseControllerName, $admin->getBaseControllerName());
99
    }
100
101
    public function testGetClass(): void
102
    {
103
        $class = Post::class;
104
        $baseControllerName = 'SonataNewsBundle:PostAdmin';
105
106
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
107
108
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
109
110
        $admin->setSubject(new BlogPost());
111
        $this->assertSame(BlogPost::class, $admin->getClass());
112
113
        $admin->setSubClasses(['foo']);
114
        $this->assertSame(BlogPost::class, $admin->getClass());
115
116
        $admin->setSubject(null);
117
        $admin->setSubClasses([]);
118
        $this->assertSame($class, $admin->getClass());
119
120
        $admin->setSubClasses(['foo' => 'bar']);
121
        $admin->setRequest(new Request(['subclass' => 'foo']));
122
        $this->assertSame('bar', $admin->getClass());
123
    }
124
125
    public function testGetClassException(): void
126
    {
127
        $this->expectException(\RuntimeException::class);
128
        $this->expectExceptionMessage('Feature not implemented: an embedded admin cannot have subclass');
129
130
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
131
        $baseControllerName = 'SonataNewsBundle:PostAdmin';
132
133
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
134
        $admin->setParentFieldDescription(new FieldDescription());
135
        $admin->setSubClasses(['foo' => 'bar']);
136
        $admin->setRequest(new Request(['subclass' => 'foo']));
137
        $admin->getClass();
138
    }
139
140
    public function testCheckAccessThrowsExceptionOnMadeUpAction(): void
141
    {
142
        $admin = new PostAdmin(
143
            'sonata.post.admin.post',
144
            'Application\Sonata\NewsBundle\Entity\Post',
145
            'SonataNewsBundle:PostAdmin'
146
        );
147
        $this->expectException(
148
            \InvalidArgumentException::class
149
        );
150
        $this->expectExceptionMessage(
151
            'Action "made-up" could not be found'
152
        );
153
        $admin->checkAccess('made-up');
154
    }
155
156
    public function testCheckAccessThrowsAccessDeniedException(): void
157
    {
158
        $admin = new PostAdmin(
159
            'sonata.post.admin.post',
160
            'Application\Sonata\NewsBundle\Entity\Post',
161
            'SonataNewsBundle:PostAdmin'
162
        );
163
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
164
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
165
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
166
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
167
        $customExtension->getAccessMapping($admin)->willReturn(
168
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
169
        );
170
        $admin->addExtension($customExtension->reveal());
171
        $admin->setSecurityHandler($securityHandler->reveal());
172
        $this->expectException(
173
            AccessDeniedException::class
174
        );
175
        $this->expectExceptionMessage(
176
            'Access Denied to the action custom_action and role EXTRA_CUSTOM_ROLE'
177
        );
178
        $admin->checkAccess('custom_action');
179
    }
180
181
    public function testHasAccessOnMadeUpAction(): void
182
    {
183
        $admin = new PostAdmin(
184
            'sonata.post.admin.post',
185
            'Application\Sonata\NewsBundle\Entity\Post',
186
            'SonataNewsBundle:PostAdmin'
187
        );
188
189
        $this->assertFalse($admin->hasAccess('made-up'));
190
    }
191
192
    public function testHasAccess(): void
193
    {
194
        $admin = new PostAdmin(
195
            'sonata.post.admin.post',
196
            'Application\Sonata\NewsBundle\Entity\Post',
197
            'SonataNewsBundle:PostAdmin'
198
        );
199
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
200
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
201
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
202
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
203
        $customExtension->getAccessMapping($admin)->willReturn(
204
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
205
        );
206
        $admin->addExtension($customExtension->reveal());
207
        $admin->setSecurityHandler($securityHandler->reveal());
208
209
        $this->assertFalse($admin->hasAccess('custom_action'));
210
    }
211
212
    public function testHasAccessAllowsAccess(): void
213
    {
214
        $admin = new PostAdmin(
215
            'sonata.post.admin.post',
216
            'Application\Sonata\NewsBundle\Entity\Post',
217
            'SonataNewsBundle:PostAdmin'
218
        );
219
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
220
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
221
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(true);
222
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
223
        $customExtension->getAccessMapping($admin)->willReturn(
224
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
225
        );
226
        $admin->addExtension($customExtension->reveal());
227
        $admin->setSecurityHandler($securityHandler->reveal());
228
229
        $this->assertTrue($admin->hasAccess('custom_action'));
230
    }
231
232
    public function testHasAccessAllowsAccessEditAction(): void
233
    {
234
        $admin = new PostAdmin(
235
            'sonata.post.admin.post',
236
            'Application\Sonata\NewsBundle\Entity\Post',
237
            'SonataNewsBundle:PostAdmin'
238
        );
239
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
240
        $securityHandler->isGranted($admin, 'EDIT_ROLE', $admin)->willReturn(true);
241
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
242
        $customExtension->getAccessMapping($admin)->willReturn(
243
            ['edit_action' => ['EDIT_ROLE']]
244
        );
245
        $admin->addExtension($customExtension->reveal());
246
        $admin->setSecurityHandler($securityHandler->reveal());
247
248
        $this->assertTrue($admin->hasAccess('edit_action'));
249
    }
250
251
    /**
252
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChild
253
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::addChild
254
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChild
255
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::isChild
256
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChildren
257
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChildren
258
     */
259
    public function testChildren(): void
260
    {
261
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
262
        $this->assertFalse($postAdmin->hasChildren());
263
        $this->assertFalse($postAdmin->hasChild('comment'));
264
265
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
266
        $postAdmin->addChild($commentAdmin, 'post');
267
268
        $this->assertTrue($postAdmin->hasChildren());
269
        $this->assertTrue($postAdmin->hasChild('sonata.post.admin.comment'));
270
271
        $this->assertSame('sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getCode());
272
        $this->assertSame('sonata.post.admin.post|sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getBaseCodeRoute());
273
        $this->assertSame($postAdmin, $postAdmin->getChild('sonata.post.admin.comment')->getParent());
274
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
275
276
        $this->assertFalse($postAdmin->isChild());
277
        $this->assertTrue($commentAdmin->isChild());
278
279
        $this->assertSame(['sonata.post.admin.comment' => $commentAdmin], $postAdmin->getChildren());
280
    }
281
282
    /**
283
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configure
284
     */
285
    public function testConfigure(): void
286
    {
287
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
288
        $this->assertNotNull($admin->getUniqid());
289
290
        $admin->initialize();
291
        $this->assertNotNull($admin->getUniqid());
292
        $this->assertSame('Post', $admin->getClassnameLabel());
293
294
        $admin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
295
        $admin->setClassnameLabel('postcomment');
296
297
        $admin->initialize();
298
        $this->assertSame('postcomment', $admin->getClassnameLabel());
299
    }
300
301
    public function testConfigureWithValidParentAssociationMapping(): void
302
    {
303
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
304
        $admin->setParentAssociationMapping('Category');
305
306
        $admin->initialize();
307
        $this->assertSame('Category', $admin->getParentAssociationMapping());
308
    }
309
310
    public function provideGetBaseRoutePattern()
311
    {
312
        return [
313
            [
314
                'Application\Sonata\NewsBundle\Entity\Post',
315
                '/sonata/news/post',
316
            ],
317
            [
318
                'Application\Sonata\NewsBundle\Document\Post',
319
                '/sonata/news/post',
320
            ],
321
            [
322
                'MyApplication\MyBundle\Entity\Post',
323
                '/myapplication/my/post',
324
            ],
325
            [
326
                'MyApplication\MyBundle\Entity\Post\Category',
327
                '/myapplication/my/post-category',
328
            ],
329
            [
330
                'MyApplication\MyBundle\Entity\Product\Category',
331
                '/myapplication/my/product-category',
332
            ],
333
            [
334
                'MyApplication\MyBundle\Entity\Other\Product\Category',
335
                '/myapplication/my/other-product-category',
336
            ],
337
            [
338
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
339
                '/cmf/foo/menu',
340
            ],
341
            [
342
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
343
                '/cmf/foo/menu',
344
            ],
345
            [
346
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
347
                '/symfony/barbar/menu',
348
            ],
349
            [
350
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
351
                '/symfony/barbar/menu-item',
352
            ],
353
            [
354
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
355
                '/cmf/foo/menu',
356
            ],
357
            [
358
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
359
                '/cmf/foo/menu',
360
            ],
361
            [
362
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
363
                '/cmf/foo/menu',
364
            ],
365
            [
366
                'AppBundle\Entity\User',
367
                '/app/user',
368
            ],
369
            [
370
                'App\Entity\User',
371
                '/app/user',
372
            ],
373
        ];
374
    }
375
376
    /**
377
     * @dataProvider provideGetBaseRoutePattern
378
     */
379
    public function testGetBaseRoutePattern($objFqn, $expected): void
380
    {
381
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
382
        $this->assertSame($expected, $admin->getBaseRoutePattern());
383
    }
384
385
    /**
386
     * @dataProvider provideGetBaseRoutePattern
387
     */
388
    public function testGetBaseRoutePatternWithChildAdmin($objFqn, $expected): void
389
    {
390
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
391
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
392
        $commentAdmin->setParent($postAdmin);
393
394
        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
395
    }
396
397
    /**
398
     * @dataProvider provideGetBaseRoutePattern
399
     */
400
    public function testGetBaseRoutePatternWithTwoNestedChildAdmin($objFqn, $expected): void
401
    {
402
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
403
        $commentAdmin = new CommentAdmin(
404
            'sonata.post.admin.comment',
405
            'Application\Sonata\NewsBundle\Entity\Comment',
406
            'SonataNewsBundle:CommentAdmin'
407
        );
408
        $commentVoteAdmin = new CommentVoteAdmin(
409
            'sonata.post.admin.comment_vote',
410
            'Application\Sonata\NewsBundle\Entity\CommentVote',
411
            'SonataNewsBundle:CommentVoteAdmin'
412
        );
413
        $commentAdmin->setParent($postAdmin);
414
        $commentVoteAdmin->setParent($commentAdmin);
415
416
        $this->assertSame($expected.'/{id}/comment/{childId}/commentvote', $commentVoteAdmin->getBaseRoutePattern());
417
    }
418
419
    public function testGetBaseRoutePatternWithSpecifedPattern(): void
420
    {
421
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostWithCustomRouteAdmin');
422
423
        $this->assertSame('/post-custom', $postAdmin->getBaseRoutePattern());
424
    }
425
426
    public function testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern(): void
427
    {
428
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
429
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentWithCustomRouteAdmin');
430
        $commentAdmin->setParent($postAdmin);
431
432
        $this->assertSame('/sonata/news/post/{id}/comment-custom', $commentAdmin->getBaseRoutePattern());
433
    }
434
435
    public function testGetBaseRoutePatternWithUnreconizedClassname(): void
436
    {
437
        $this->expectException(\RuntimeException::class);
438
439
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'SonataNewsBundle:PostAdmin');
440
        $admin->getBaseRoutePattern();
441
    }
442
443
    public function provideGetBaseRouteName()
444
    {
445
        return [
446
            [
447
                'Application\Sonata\NewsBundle\Entity\Post',
448
                'admin_sonata_news_post',
449
            ],
450
            [
451
                'Application\Sonata\NewsBundle\Document\Post',
452
                'admin_sonata_news_post',
453
            ],
454
            [
455
                'MyApplication\MyBundle\Entity\Post',
456
                'admin_myapplication_my_post',
457
            ],
458
            [
459
                'MyApplication\MyBundle\Entity\Post\Category',
460
                'admin_myapplication_my_post_category',
461
            ],
462
            [
463
                'MyApplication\MyBundle\Entity\Product\Category',
464
                'admin_myapplication_my_product_category',
465
            ],
466
            [
467
                'MyApplication\MyBundle\Entity\Other\Product\Category',
468
                'admin_myapplication_my_other_product_category',
469
            ],
470
            [
471
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
472
                'admin_cmf_foo_menu',
473
            ],
474
            [
475
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
476
                'admin_cmf_foo_menu',
477
            ],
478
            [
479
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
480
                'admin_symfony_barbar_menu',
481
            ],
482
            [
483
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
484
                'admin_symfony_barbar_menu_item',
485
            ],
486
            [
487
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
488
                'admin_cmf_foo_menu',
489
            ],
490
            [
491
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
492
                'admin_cmf_foo_menu',
493
            ],
494
            [
495
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
496
                'admin_cmf_foo_menu',
497
            ],
498
            [
499
                'AppBundle\Entity\User',
500
                'admin_app_user',
501
            ],
502
            [
503
                'App\Entity\User',
504
                'admin_app_user',
505
            ],
506
        ];
507
    }
508
509
    /**
510
     * @dataProvider provideGetBaseRouteName
511
     */
512
    public function testGetBaseRouteName($objFqn, $expected): void
513
    {
514
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
515
516
        $this->assertSame($expected, $admin->getBaseRouteName());
517
    }
518
519
    /**
520
     * @group legacy
521
     * @expectedDeprecation Calling "addChild" without second argument is deprecated since 3.35 and will not be allowed in 4.0.
522
     * @dataProvider provideGetBaseRouteName
523
     */
524
    public function testGetBaseRouteNameWithChildAdmin($objFqn, $expected): void
525
    {
526
        $routeGenerator = new DefaultRouteGenerator(
527
            $this->createMock(RouterInterface::class),
528
            new RoutesCache($this->cacheTempFolder, true)
529
        );
530
531
        $container = new Container();
532
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
533
534
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
535
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
536
        $container->set('sonata.post.admin.post', $postAdmin);
537
        $postAdmin->setConfigurationPool($pool);
538
        $postAdmin->setRouteBuilder($pathInfo);
539
        $postAdmin->setRouteGenerator($routeGenerator);
540
        $postAdmin->initialize();
541
542
        $commentAdmin = new CommentAdmin(
543
            'sonata.post.admin.comment',
544
            'Application\Sonata\NewsBundle\Entity\Comment',
545
            'SonataNewsBundle:CommentAdmin'
546
        );
547
        $container->set('sonata.post.admin.comment', $commentAdmin);
548
        $commentAdmin->setConfigurationPool($pool);
549
        $commentAdmin->setRouteBuilder($pathInfo);
550
        $commentAdmin->setRouteGenerator($routeGenerator);
551
        $commentAdmin->initialize();
552
553
        $postAdmin->addChild($commentAdmin, 'post');
554
555
        $commentVoteAdmin = new CommentVoteAdmin(
556
            'sonata.post.admin.comment_vote',
557
            'Application\Sonata\NewsBundle\Entity\CommentVote',
558
            'SonataNewsBundle:CommentVoteAdmin'
559
        );
560
561
        $container->set('sonata.post.admin.comment_vote', $commentVoteAdmin);
562
        $commentVoteAdmin->setConfigurationPool($pool);
563
        $commentVoteAdmin->setRouteBuilder($pathInfo);
564
        $commentVoteAdmin->setRouteGenerator($routeGenerator);
565
        $commentVoteAdmin->initialize();
566
567
        $commentAdmin->addChild($commentVoteAdmin);
568
        $pool->setAdminServiceIds([
569
            'sonata.post.admin.post',
570
            'sonata.post.admin.comment',
571
            'sonata.post.admin.comment_vote',
572
        ]);
573
574
        $this->assertSame($expected.'_comment', $commentAdmin->getBaseRouteName());
575
576
        $this->assertTrue($postAdmin->hasRoute('show'));
577
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
578
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.show'));
579
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment|sonata.post.admin.comment_vote.show'));
580
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment.list'));
581
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment|sonata.post.admin.comment_vote.list'));
582
        $this->assertFalse($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.edit'));
583
        $this->assertFalse($commentAdmin->hasRoute('edit'));
584
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
585
586
        /*
587
         * Test the route name from request
588
         */
589
        $postListRequest = new Request(
590
            [],
591
            [],
592
            [
593
                '_route' => $postAdmin->getBaseRouteName().'_list',
594
            ]
595
        );
596
597
        $postAdmin->setRequest($postListRequest);
598
        $commentAdmin->setRequest($postListRequest);
599
600
        $this->assertTrue($postAdmin->isCurrentRoute('list'));
601
        $this->assertFalse($postAdmin->isCurrentRoute('create'));
602
        $this->assertFalse($commentAdmin->isCurrentRoute('list'));
603
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('list'));
604
        $this->assertTrue($commentAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
605
        $this->assertFalse($commentAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
606
        $this->assertTrue($commentVoteAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
607
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
608
    }
609
610
    public function testGetBaseRouteNameWithUnreconizedClassname(): void
611
    {
612
        $this->expectException(\RuntimeException::class);
613
614
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'SonataNewsBundle:PostAdmin');
615
        $admin->getBaseRouteName();
616
    }
617
618
    public function testGetBaseRouteNameWithSpecifiedName(): void
619
    {
620
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
621
622
        $this->assertSame('post_custom', $postAdmin->getBaseRouteName());
623
    }
624
625
    public function testGetBaseRouteNameWithChildAdminAndWithSpecifiedName(): void
626
    {
627
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
628
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentWithCustomRouteAdmin');
629
        $commentAdmin->setParent($postAdmin);
630
631
        $this->assertSame('admin_sonata_news_post_comment_custom', $commentAdmin->getBaseRouteName());
632
    }
633
634
    public function testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName(): void
635
    {
636
        $postAdmin = new PostAdmin(
637
            'sonata.post.admin.post',
638
            'Application\Sonata\NewsBundle\Entity\Post',
639
            'SonataNewsBundle:PostAdmin'
640
        );
641
        $commentAdmin = new CommentWithCustomRouteAdmin(
642
            'sonata.post.admin.comment_with_custom_route',
643
            'Application\Sonata\NewsBundle\Entity\Comment',
644
            'SonataNewsBundle:CommentWithCustomRouteAdmin'
645
        );
646
        $commentVoteAdmin = new CommentVoteAdmin(
647
            'sonata.post.admin.comment_vote',
648
            'Application\Sonata\NewsBundle\Entity\CommentVote',
649
            'SonataNewsBundle:CommentVoteAdmin'
650
        );
651
        $commentAdmin->setParent($postAdmin);
652
        $commentVoteAdmin->setParent($commentAdmin);
653
654
        $this->assertSame('admin_sonata_news_post_comment_custom_commentvote', $commentVoteAdmin->getBaseRouteName());
655
    }
656
657
    /**
658
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setUniqid
659
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getUniqid
660
     */
661
    public function testSetUniqid(): void
662
    {
663
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
664
665
        $uniqid = uniqid();
666
        $admin->setUniqid($uniqid);
667
668
        $this->assertSame($uniqid, $admin->getUniqid());
669
    }
670
671
    public function testUniqidConsistency(): void
672
    {
673
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
674
            'sonata.abstract.admin',
675
            'AbstractBundle\Entity\Foo',
676
            'SonataAbstractBundle:FooAdmin',
677
        ]);
678
        $admin->initialize();
679
680
        $uniqid = $admin->getUniqid();
681
        $admin->setUniqid(null);
682
683
        $this->assertSame($uniqid, $admin->getUniqid());
684
685
        $parentAdmin = $this->getMockForAbstractClass(AbstractAdmin::class, [
686
            'sonata.abstract.parent.admin',
687
            'AbstractBundle\Entity\Bar',
688
            'SonataAbstractBundle:BarAdmin',
689
        ]);
690
        $parentAdmin->initialize();
691
692
        $admin->setParent($parentAdmin);
693
        $admin->setUniqid(null);
694
695
        $this->assertNotSame($uniqid, $admin->getUniqid());
696
    }
697
698
    public function testToString(): void
699
    {
700
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
701
702
        $s = new \stdClass();
703
704
        $this->assertNotEmpty($admin->toString($s));
705
706
        $s = new FooToString();
707
        $this->assertSame('salut', $admin->toString($s));
708
709
        // To string method is implemented, but returns null
710
        $s = new FooToStringNull();
711
        $this->assertNotEmpty($admin->toString($s));
712
713
        $this->assertSame('', $admin->toString(false));
714
    }
715
716
    public function testIsAclEnabled(): void
717
    {
718
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
719
720
        $this->assertFalse($postAdmin->isAclEnabled());
721
722
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
723
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
724
        $this->assertTrue($commentAdmin->isAclEnabled());
725
    }
726
727
    /**
728
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
729
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
730
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
731
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
732
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
733
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
734
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
735
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
736
     */
737
    public function testSubClass(): void
738
    {
739
        $admin = new PostAdmin(
740
            'sonata.post.admin.post',
741
            Post::class,
742
            'SonataNewsBundle:PostAdmin'
743
        );
744
        $this->assertFalse($admin->hasSubClass('test'));
745
        $this->assertFalse($admin->hasActiveSubClass());
746
        $this->assertCount(0, $admin->getSubClasses());
747
        $this->assertNull($admin->getActiveSubClass());
748
        $this->assertNull($admin->getActiveSubclassCode());
749
        $this->assertSame(Post::class, $admin->getClass());
750
751
        // Just for the record, if there is no inheritance set, the getSubject is not used
752
        // the getSubject can also lead to some issue
753
        $admin->setSubject(new BlogPost());
754
        $this->assertSame(BlogPost::class, $admin->getClass());
755
756
        $admin->setSubClasses([
757
            'extended1' => 'NewsBundle\Entity\PostExtended1',
758
            'extended2' => 'NewsBundle\Entity\PostExtended2',
759
        ]);
760
        $this->assertFalse($admin->hasSubClass('test'));
761
        $this->assertTrue($admin->hasSubClass('extended1'));
762
        $this->assertFalse($admin->hasActiveSubClass());
763
        $this->assertCount(2, $admin->getSubClasses());
764
        $this->assertNull($admin->getActiveSubClass());
765
        $this->assertNull($admin->getActiveSubclassCode());
766
        $this->assertSame(
767
            BlogPost::class,
768
            $admin->getClass(),
769
            'When there is no subclass in the query the class parameter should be returned'
770
        );
771
772
        $request = new Request(['subclass' => 'extended1']);
773
        $admin->setRequest($request);
774
        $this->assertFalse($admin->hasSubClass('test'));
775
        $this->assertTrue($admin->hasSubClass('extended1'));
776
        $this->assertTrue($admin->hasActiveSubClass());
777
        $this->assertCount(2, $admin->getSubClasses());
778
        $this->assertSame(
779
            'NewsBundle\Entity\PostExtended1',
780
            $admin->getActiveSubClass(),
781
            'It should return the curently active sub class.'
782
        );
783
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
784
        $this->assertSame(
785
            'NewsBundle\Entity\PostExtended1',
786
            $admin->getClass(),
787
            'getClass() should return the name of the sub class when passed through a request query parameter.'
788
        );
789
790
        $request->query->set('subclass', 'inject');
791
        $this->assertNull($admin->getActiveSubclassCode());
792
    }
793
794
    public function testNonExistantSubclass(): void
795
    {
796
        $this->expectException(\RuntimeException::class);
797
798
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
799
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
800
801
        $admin->setRequest(new Request(['subclass' => 'inject']));
802
803
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
804
805
        $this->assertTrue($admin->hasActiveSubClass());
806
807
        $admin->getActiveSubClass();
808
    }
809
810
    /**
811
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
812
     */
813
    public function testOnlyOneSubclassNeededToBeActive(): void
814
    {
815
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
816
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
817
        $request = new Request(['subclass' => 'extended1']);
818
        $admin->setRequest($request);
819
        $this->assertTrue($admin->hasActiveSubClass());
820
    }
821
822
    /**
823
     * @group legacy
824
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since 3.30 and will be removed in 4.0.
825
     */
826
    public function testAddSubClassIsDeprecated(): void
827
    {
828
        $admin = new PostAdmin(
829
            'sonata.post.admin.post',
830
            Post::class,
831
            'SonataNewsBundle:PostAdmin'
832
        );
833
        $admin->addSubClass('whatever');
834
    }
835
836
    public function testGetPerPageOptions(): void
837
    {
838
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
839
840
        $perPageOptions = $admin->getPerPageOptions();
841
842
        foreach ($perPageOptions as $perPage) {
843
            $this->assertSame(0, $perPage % 4);
844
        }
845
846
        $admin->setPerPageOptions([500, 1000]);
847
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
848
    }
849
850
    public function testGetLabelTranslatorStrategy(): void
851
    {
852
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
853
854
        $this->assertNull($admin->getLabelTranslatorStrategy());
855
856
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
857
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
858
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
859
    }
860
861
    public function testGetRouteBuilder(): void
862
    {
863
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
864
865
        $this->assertNull($admin->getRouteBuilder());
866
867
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
868
        $admin->setRouteBuilder($routeBuilder);
869
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
870
    }
871
872
    public function testGetMenuFactory(): void
873
    {
874
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
875
876
        $this->assertNull($admin->getMenuFactory());
877
878
        $menuFactory = $this->createMock(FactoryInterface::class);
879
        $admin->setMenuFactory($menuFactory);
880
        $this->assertSame($menuFactory, $admin->getMenuFactory());
881
    }
882
883
    public function testGetExtensions(): void
884
    {
885
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
886
887
        $this->assertSame([], $admin->getExtensions());
888
889
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
890
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
891
892
        $admin->addExtension($adminExtension1);
893
        $admin->addExtension($adminExtension2);
894
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
895
    }
896
897
    public function testGetFilterTheme(): void
898
    {
899
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
900
901
        $this->assertSame([], $admin->getFilterTheme());
902
903
        $admin->setFilterTheme(['FooTheme']);
904
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
905
    }
906
907
    public function testGetFormTheme(): void
908
    {
909
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
910
911
        $this->assertSame([], $admin->getFormTheme());
912
913
        $admin->setFormTheme(['FooTheme']);
914
915
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
916
    }
917
918
    public function testGetValidator(): void
919
    {
920
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
921
922
        $this->assertNull($admin->getValidator());
923
924
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
925
926
        $admin->setValidator($validator);
927
        $this->assertSame($validator, $admin->getValidator());
928
    }
929
930
    public function testGetSecurityHandler(): void
931
    {
932
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
933
934
        $this->assertNull($admin->getSecurityHandler());
935
936
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
937
        $admin->setSecurityHandler($securityHandler);
938
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
939
    }
940
941
    public function testGetSecurityInformation(): void
942
    {
943
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
944
945
        $this->assertSame([], $admin->getSecurityInformation());
946
947
        $securityInformation = [
948
            'GUEST' => ['VIEW', 'LIST'],
949
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
950
        ];
951
952
        $admin->setSecurityInformation($securityInformation);
953
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
954
    }
955
956
    public function testGetManagerType(): void
957
    {
958
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
959
960
        $this->assertNull($admin->getManagerType());
961
962
        $admin->setManagerType('foo_orm');
963
        $this->assertSame('foo_orm', $admin->getManagerType());
964
    }
965
966
    public function testGetModelManager(): void
967
    {
968
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
969
970
        $this->assertNull($admin->getModelManager());
971
972
        $modelManager = $this->createMock(ModelManagerInterface::class);
973
974
        $admin->setModelManager($modelManager);
975
        $this->assertSame($modelManager, $admin->getModelManager());
976
    }
977
978
    /**
979
     * NEXT_MAJOR: remove this method.
980
     *
981
     * @group legacy
982
     */
983
    public function testGetBaseCodeRoute(): void
984
    {
985
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
986
987
        $this->assertSame('', $admin->getBaseCodeRoute());
988
989
        $admin->setBaseCodeRoute('foo');
990
        $this->assertSame('foo', $admin->getBaseCodeRoute());
991
    }
992
993
    // NEXT_MAJOR: uncomment this method.
994
    // public function testGetBaseCodeRoute()
995
    // {
996
    //     $postAdmin = new PostAdmin(
997
    //         'sonata.post.admin.post',
998
    //         'NewsBundle\Entity\Post',
999
    //         'SonataNewsBundle:PostAdmin'
1000
    //     );
1001
    //     $commentAdmin = new CommentAdmin(
1002
    //         'sonata.post.admin.comment',
1003
    //         'Application\Sonata\NewsBundle\Entity\Comment',
1004
    //         'SonataNewsBundle:CommentAdmin'
1005
    //     );
1006
    //
1007
    //     $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
1008
    //
1009
    //     $postAdmin->addChild($commentAdmin);
1010
    //
1011
    //     $this->assertSame(
1012
    //         'sonata.post.admin.post|sonata.post.admin.comment',
1013
    //         $commentAdmin->getBaseCodeRoute()
1014
    //     );
1015
    // }
1016
1017
    public function testGetRouteGenerator(): void
1018
    {
1019
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1020
1021
        $this->assertNull($admin->getRouteGenerator());
1022
1023
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1024
1025
        $admin->setRouteGenerator($routeGenerator);
1026
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1027
    }
1028
1029
    public function testGetConfigurationPool(): void
1030
    {
1031
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1032
1033
        $this->assertNull($admin->getConfigurationPool());
1034
1035
        $pool = $this->getMockBuilder(Pool::class)
1036
            ->disableOriginalConstructor()
1037
            ->getMock();
1038
1039
        $admin->setConfigurationPool($pool);
1040
        $this->assertSame($pool, $admin->getConfigurationPool());
1041
    }
1042
1043
    public function testGetShowBuilder(): void
1044
    {
1045
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1046
1047
        $this->assertNull($admin->getShowBuilder());
1048
1049
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1050
1051
        $admin->setShowBuilder($showBuilder);
1052
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1053
    }
1054
1055
    public function testGetListBuilder(): void
1056
    {
1057
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1058
1059
        $this->assertNull($admin->getListBuilder());
1060
1061
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1062
1063
        $admin->setListBuilder($listBuilder);
1064
        $this->assertSame($listBuilder, $admin->getListBuilder());
1065
    }
1066
1067
    public function testGetDatagridBuilder(): void
1068
    {
1069
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1070
1071
        $this->assertNull($admin->getDatagridBuilder());
1072
1073
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1074
1075
        $admin->setDatagridBuilder($datagridBuilder);
1076
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1077
    }
1078
1079
    public function testGetFormContractor(): void
1080
    {
1081
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1082
1083
        $this->assertNull($admin->getFormContractor());
1084
1085
        $formContractor = $this->createMock(FormContractorInterface::class);
1086
1087
        $admin->setFormContractor($formContractor);
1088
        $this->assertSame($formContractor, $admin->getFormContractor());
1089
    }
1090
1091
    public function testGetRequest(): void
1092
    {
1093
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1094
1095
        $this->assertFalse($admin->hasRequest());
1096
1097
        $request = new Request();
1098
1099
        $admin->setRequest($request);
1100
        $this->assertSame($request, $admin->getRequest());
1101
        $this->assertTrue($admin->hasRequest());
1102
    }
1103
1104
    public function testGetRequestWithException(): void
1105
    {
1106
        $this->expectException(\RuntimeException::class);
1107
        $this->expectExceptionMessage('The Request object has not been set');
1108
1109
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1110
        $admin->getRequest();
1111
    }
1112
1113
    public function testGetTranslationDomain(): void
1114
    {
1115
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1116
1117
        $this->assertSame('messages', $admin->getTranslationDomain());
1118
1119
        $admin->setTranslationDomain('foo');
1120
        $this->assertSame('foo', $admin->getTranslationDomain());
1121
    }
1122
1123
    /**
1124
     * @group legacy
1125
     */
1126
    public function testGetTranslator(): void
1127
    {
1128
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1129
1130
        $this->assertNull($admin->getTranslator());
1131
1132
        $translator = $this->createMock(TranslatorInterface::class);
1133
1134
        $admin->setTranslator($translator);
1135
        $this->assertSame($translator, $admin->getTranslator());
1136
    }
1137
1138
    public function testGetShowGroups(): void
1139
    {
1140
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1141
1142
        $this->assertFalse($admin->getShowGroups());
1143
1144
        $groups = ['foo', 'bar', 'baz'];
1145
1146
        $admin->setShowGroups($groups);
1147
        $this->assertSame($groups, $admin->getShowGroups());
1148
    }
1149
1150
    public function testGetFormGroups(): void
1151
    {
1152
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1153
1154
        $this->assertFalse($admin->getFormGroups());
1155
1156
        $groups = ['foo', 'bar', 'baz'];
1157
1158
        $admin->setFormGroups($groups);
1159
        $this->assertSame($groups, $admin->getFormGroups());
1160
    }
1161
1162
    public function testGetMaxPageLinks(): void
1163
    {
1164
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1165
1166
        $this->assertSame(25, $admin->getMaxPageLinks());
1167
1168
        $admin->setMaxPageLinks(14);
1169
        $this->assertSame(14, $admin->getMaxPageLinks());
1170
    }
1171
1172
    public function testGetMaxPerPage(): void
1173
    {
1174
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1175
1176
        $this->assertSame(32, $admin->getMaxPerPage());
1177
1178
        $admin->setMaxPerPage(94);
1179
        $this->assertSame(94, $admin->getMaxPerPage());
1180
    }
1181
1182
    public function testGetLabel(): void
1183
    {
1184
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1185
1186
        $this->assertNull($admin->getLabel());
1187
1188
        $admin->setLabel('FooLabel');
1189
        $this->assertSame('FooLabel', $admin->getLabel());
1190
    }
1191
1192
    public function testGetBaseController(): void
1193
    {
1194
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1195
1196
        $this->assertSame('SonataNewsBundle:PostAdmin', $admin->getBaseControllerName());
1197
1198
        $admin->setBaseControllerName('SonataNewsBundle:FooAdmin');
1199
        $this->assertSame('SonataNewsBundle:FooAdmin', $admin->getBaseControllerName());
1200
    }
1201
1202
    public function testGetTemplates(): void
1203
    {
1204
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1205
1206
        $templates = [
1207
            'list' => '@FooAdmin/CRUD/list.html.twig',
1208
            'show' => '@FooAdmin/CRUD/show.html.twig',
1209
            'edit' => '@FooAdmin/CRUD/edit.html.twig',
1210
        ];
1211
1212
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1213
        $templateRegistry->getTemplates()->shouldBeCalled()->willReturn($templates);
1214
1215
        $admin->setTemplateRegistry($templateRegistry->reveal());
1216
1217
        $this->assertSame($templates, $admin->getTemplates());
1218
    }
1219
1220
    public function testGetTemplate1(): void
1221
    {
1222
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1223
1224
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1225
        $templateRegistry->getTemplate('edit')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/edit.html.twig');
1226
        $templateRegistry->getTemplate('show')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/show.html.twig');
1227
1228
        $admin->setTemplateRegistry($templateRegistry->reveal());
1229
1230
        $this->assertSame('@FooAdmin/CRUD/edit.html.twig', $admin->getTemplate('edit'));
1231
        $this->assertSame('@FooAdmin/CRUD/show.html.twig', $admin->getTemplate('show'));
1232
    }
1233
1234
    public function testGetIdParameter(): void
1235
    {
1236
        $postAdmin = new PostAdmin(
1237
            'sonata.post.admin.post',
1238
            'NewsBundle\Entity\Post',
1239
            'SonataNewsBundle:PostAdmin'
1240
        );
1241
1242
        $this->assertSame('id', $postAdmin->getIdParameter());
1243
        $this->assertFalse($postAdmin->isChild());
1244
1245
        $commentAdmin = new CommentAdmin(
1246
            'sonata.post.admin.comment',
1247
            'Application\Sonata\NewsBundle\Entity\Comment',
1248
            'SonataNewsBundle:CommentAdmin'
1249
        );
1250
        $commentAdmin->setParent($postAdmin);
1251
1252
        $this->assertTrue($commentAdmin->isChild());
1253
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1254
1255
        $commentVoteAdmin = new CommentVoteAdmin(
1256
            'sonata.post.admin.comment_vote',
1257
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1258
            'SonataNewsBundle:CommentVoteAdmin'
1259
        );
1260
        $commentVoteAdmin->setParent($commentAdmin);
1261
1262
        $this->assertTrue($commentVoteAdmin->isChild());
1263
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1264
    }
1265
1266
    public function testGetExportFormats(): void
1267
    {
1268
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1269
1270
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1271
    }
1272
1273
    public function testGetUrlsafeIdentifier(): void
1274
    {
1275
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1276
1277
        $entity = new \stdClass();
1278
1279
        $modelManager = $this->createMock(ModelManagerInterface::class);
1280
        $modelManager->expects($this->once())
1281
            ->method('getUrlsafeIdentifier')
1282
            ->with($this->equalTo($entity))
1283
            ->will($this->returnValue('foo'));
1284
        $admin->setModelManager($modelManager);
1285
1286
        $this->assertSame('foo', $admin->getUrlsafeIdentifier($entity));
1287
    }
1288
1289
    public function testDeterminedPerPageValue(): void
1290
    {
1291
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1292
1293
        $this->assertFalse($admin->determinedPerPageValue('foo'));
1294
        $this->assertFalse($admin->determinedPerPageValue(123));
1295
        $this->assertTrue($admin->determinedPerPageValue(16));
1296
1297
        $admin->setPerPageOptions([101, 102, 103]);
1298
        $this->assertFalse($admin->determinedPerPageValue(16));
1299
        $this->assertTrue($admin->determinedPerPageValue(101));
1300
    }
1301
1302
    public function testIsGranted(): void
1303
    {
1304
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1305
1306
        $entity = new \stdClass();
1307
1308
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1309
        $securityHandler->expects($this->any())
1310
            ->method('isGranted')
1311
            ->will($this->returnCallback(function (AdminInterface $adminIn, $attributes, $object = null) use ($admin, $entity) {
1312
                if ($admin === $adminIn && 'FOO' === $attributes) {
1313
                    if (($object === $admin) || ($object === $entity)) {
1314
                        return true;
1315
                    }
1316
                }
1317
1318
                return false;
1319
            }));
1320
1321
        $admin->setSecurityHandler($securityHandler);
1322
1323
        $this->assertTrue($admin->isGranted('FOO'));
1324
        $this->assertTrue($admin->isGranted('FOO', $entity));
1325
        $this->assertFalse($admin->isGranted('BAR'));
1326
        $this->assertFalse($admin->isGranted('BAR', $entity));
1327
    }
1328
1329
    public function testSupportsPreviewMode(): void
1330
    {
1331
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1332
1333
        $this->assertFalse($admin->supportsPreviewMode());
1334
    }
1335
1336
    public function testGetPermissionsShow(): void
1337
    {
1338
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1339
1340
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1341
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1342
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1343
    }
1344
1345
    public function testShowIn(): void
1346
    {
1347
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1348
1349
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1350
        $securityHandler->expects($this->any())
1351
            ->method('isGranted')
1352
            ->will($this->returnCallback(function (AdminInterface $adminIn, $attributes, $object = null) use ($admin) {
1353
                if ($admin === $adminIn && $attributes === ['LIST']) {
1354
                    return true;
1355
                }
1356
1357
                return false;
1358
            }));
1359
1360
        $admin->setSecurityHandler($securityHandler);
1361
1362
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1363
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1364
        $this->assertTrue($admin->showIn('foo'));
1365
    }
1366
1367
    public function testGetObjectIdentifier(): void
1368
    {
1369
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1370
1371
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1372
    }
1373
1374
    /**
1375
     * @group legacy
1376
     */
1377
    public function testTrans(): void
1378
    {
1379
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1380
        $admin->setTranslationDomain('fooMessageDomain');
1381
1382
        $translator = $this->createMock(TranslatorInterface::class);
1383
        $admin->setTranslator($translator);
1384
1385
        $translator->expects($this->once())
1386
            ->method('trans')
1387
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1388
            ->will($this->returnValue('fooTranslated'));
1389
1390
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1391
    }
1392
1393
    /**
1394
     * @group legacy
1395
     */
1396
    public function testTransWithMessageDomain(): void
1397
    {
1398
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1399
1400
        $translator = $this->createMock(TranslatorInterface::class);
1401
        $admin->setTranslator($translator);
1402
1403
        $translator->expects($this->once())
1404
            ->method('trans')
1405
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1406
            ->will($this->returnValue('fooTranslated'));
1407
1408
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1409
    }
1410
1411
    /**
1412
     * @group legacy
1413
     */
1414
    public function testTransChoice(): void
1415
    {
1416
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1417
        $admin->setTranslationDomain('fooMessageDomain');
1418
1419
        $translator = $this->createMock(TranslatorInterface::class);
1420
        $admin->setTranslator($translator);
1421
1422
        $translator->expects($this->once())
1423
            ->method('transChoice')
1424
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1425
            ->will($this->returnValue('fooTranslated'));
1426
1427
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2));
1428
    }
1429
1430
    /**
1431
     * @group legacy
1432
     */
1433
    public function testTransChoiceWithMessageDomain(): void
1434
    {
1435
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1436
1437
        $translator = $this->createMock(TranslatorInterface::class);
1438
        $admin->setTranslator($translator);
1439
1440
        $translator->expects($this->once())
1441
            ->method('transChoice')
1442
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1443
            ->will($this->returnValue('fooTranslated'));
1444
1445
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2, ['name' => 'Andrej'], 'fooMessageDomain'));
1446
    }
1447
1448
    public function testSetFilterPersister(): void
1449
    {
1450
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1451
1452
        $filterPersister = $this->createMock('Sonata\AdminBundle\Filter\Persister\FilterPersisterInterface');
1453
1454
        $this->assertAttributeSame(null, 'filterPersister', $admin);
1455
        $admin->setFilterPersister($filterPersister);
1456
        $this->assertAttributeSame($filterPersister, 'filterPersister', $admin);
1457
        $this->assertAttributeSame(true, 'persistFilters', $admin);
1458
    }
1459
1460
    public function testGetRootCode(): void
1461
    {
1462
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1463
1464
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1465
1466
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'SonataNewsBundle:PostParentAdmin');
1467
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1468
        $parentFieldDescription->expects($this->once())
1469
            ->method('getAdmin')
1470
            ->will($this->returnValue($parentAdmin));
1471
1472
        $this->assertNull($admin->getParentFieldDescription());
1473
        $admin->setParentFieldDescription($parentFieldDescription);
1474
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1475
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1476
    }
1477
1478
    public function testGetRoot(): void
1479
    {
1480
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1481
1482
        $this->assertSame($admin, $admin->getRoot());
1483
1484
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'SonataNewsBundle:PostParentAdmin');
1485
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1486
        $parentFieldDescription->expects($this->once())
1487
            ->method('getAdmin')
1488
            ->will($this->returnValue($parentAdmin));
1489
1490
        $this->assertNull($admin->getParentFieldDescription());
1491
        $admin->setParentFieldDescription($parentFieldDescription);
1492
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1493
        $this->assertSame($parentAdmin, $admin->getRoot());
1494
    }
1495
1496
    public function testGetExportFields(): void
1497
    {
1498
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1499
1500
        $modelManager = $this->createMock(ModelManagerInterface::class);
1501
        $modelManager->expects($this->once())
1502
            ->method('getExportFields')
1503
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1504
            ->will($this->returnValue(['foo', 'bar']));
1505
1506
        $admin->setModelManager($modelManager);
1507
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1508
    }
1509
1510
    public function testGetPersistentParametersWithNoExtension(): void
1511
    {
1512
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1513
1514
        $this->assertEmpty($admin->getPersistentParameters());
1515
    }
1516
1517
    public function testGetPersistentParametersWithInvalidExtension(): void
1518
    {
1519
        $this->expectException(\RuntimeException::class);
1520
1521
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1522
1523
        $extension = $this->createMock(AdminExtensionInterface::class);
1524
        $extension->expects($this->once())->method('getPersistentParameters')->will($this->returnValue(null));
1525
1526
        $admin->addExtension($extension);
1527
1528
        $admin->getPersistentParameters();
1529
    }
1530
1531
    public function testGetPersistentParametersWithValidExtension(): void
1532
    {
1533
        $expected = [
1534
            'context' => 'foobar',
1535
        ];
1536
1537
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1538
1539
        $extension = $this->createMock(AdminExtensionInterface::class);
1540
        $extension->expects($this->once())->method('getPersistentParameters')->will($this->returnValue($expected));
1541
1542
        $admin->addExtension($extension);
1543
1544
        $this->assertSame($expected, $admin->getPersistentParameters());
1545
    }
1546
1547
    public function testGetFormWithNonCollectionParentValue(): void
1548
    {
1549
        $post = new Post();
1550
        $tagAdmin = $this->createTagAdmin($post);
1551
        $tag = $tagAdmin->getSubject();
1552
1553
        $tag->setPosts(null);
1554
        $tagAdmin->getForm();
1555
        $this->assertSame($post, $tag->getPosts());
1556
    }
1557
1558
    public function testGetFormWithCollectionParentValue(): void
1559
    {
1560
        $post = new Post();
1561
        $tagAdmin = $this->createTagAdmin($post);
1562
        $tag = $tagAdmin->getSubject();
1563
1564
        // Case of a doctrine collection
1565
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1566
        $this->assertCount(0, $tag->getPosts());
1567
1568
        $tag->addPost(new Post());
1569
1570
        $this->assertCount(1, $tag->getPosts());
1571
1572
        $tagAdmin->getForm();
1573
1574
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1575
        $this->assertCount(2, $tag->getPosts());
1576
        $this->assertContains($post, $tag->getPosts());
1577
1578
        // Case of an array
1579
        $tag->setPosts([]);
1580
        $this->assertCount(0, $tag->getPosts());
1581
1582
        $tag->addPost(new Post());
1583
1584
        $this->assertCount(1, $tag->getPosts());
1585
1586
        $tagAdmin->getForm();
1587
1588
        $this->assertInternalType('array', $tag->getPosts());
1589
        $this->assertCount(2, $tag->getPosts());
1590
        $this->assertContains($post, $tag->getPosts());
1591
    }
1592
1593
    public function testFormAddPostSubmitEventForPreValidation(): void
1594
    {
1595
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
1596
        $object = new \stdClass();
1597
1598
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1599
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1600
1601
        $validator = $this->createMock(ValidatorInterface::class);
1602
        $validator->expects($this->any())
1603
                ->method('getMetadataFor')
1604
                ->will($this->returnValue($this->createMock(MemberMetadata::class)));
1605
        $modelAdmin->setValidator($validator);
1606
1607
        $modelManager = $this->createMock(ModelManagerInterface::class);
1608
        $modelManager->expects($this->any())
1609
            ->method('getNewFieldDescriptionInstance')
1610
            ->will($this->returnValue(new FieldDescription()));
1611
        $modelAdmin->setModelManager($modelManager);
1612
1613
        // a Admin class to test that preValidate is called
1614
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class, ['preValidate']);
1615
        $testAdminPreValidate->expects($this->once())
1616
                ->method('preValidate')
1617
                ->with($this->identicalTo($object));
1618
1619
        $event = $this->createMock(FormEvent::class);
1620
        $event->expects($this->any())
1621
                ->method('getData')
1622
                ->will($this->returnValue($object));
1623
1624
        $formBuild = $this->createMock(FormBuilder::class, ['addEventListener']);
1625
        $formBuild->expects($this->once())
1626
                ->method('addEventListener')
1627
                ->with($this->identicalTo(FormEvents::POST_SUBMIT),
1628
                        $this->callback(function ($callback) use ($testAdminPreValidate, $event) {
1629
                            if (\is_callable($callback)) {
1630
                                $closure = $callback->bindTo($testAdminPreValidate);
1631
                                $closure($event);
1632
1633
                                return true;
1634
                            }
1635
1636
                            return false;
1637
                        }),
1638
                        $this->greaterThan(0)
1639
                    );
1640
1641
        $formContractor = $this->createMock(FormContractorInterface::class, ['getDefaultOptions', 'getFormBuilder']);
1642
        $formContractor->expects($this->any())
1643
                ->method('getDefaultOptions')
1644
                ->will($this->returnValue([]));
1645
        $formContractor->expects($this->any())
1646
                ->method('getFormBuilder')
1647
                ->will($this->returnValue($formBuild));
1648
1649
        $modelAdmin->setFormContractor($formContractor);
1650
        $modelAdmin->defineFormBuilder($formBuild);
1651
        $modelAdmin->getForm();
1652
    }
1653
1654
    public function testRemoveFieldFromFormGroup(): void
1655
    {
1656
        $formGroups = [
1657
            'foobar' => [
1658
                'fields' => [
1659
                    'foo' => 'foo',
1660
                    'bar' => 'bar',
1661
                ],
1662
            ],
1663
        ];
1664
1665
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1666
        $admin->setFormGroups($formGroups);
1667
1668
        $admin->removeFieldFromFormGroup('foo');
1669
        $this->assertSame($admin->getFormGroups(), [
1670
            'foobar' => [
1671
                'fields' => [
1672
                    'bar' => 'bar',
1673
                ],
1674
            ],
1675
        ]);
1676
1677
        $admin->removeFieldFromFormGroup('bar');
1678
        $this->assertSame($admin->getFormGroups(), []);
1679
    }
1680
1681
    public function testGetFilterParameters(): void
1682
    {
1683
        $authorId = uniqid();
1684
1685
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1686
1687
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
1688
        $commentAdmin->setParentAssociationMapping('post.author');
1689
        $commentAdmin->setParent($postAdmin);
1690
1691
        $request = $this->createMock(Request::class, ['get']);
1692
        $query = $this->createMock(ParameterBag::class, ['get']);
1693
        $query->expects($this->any())
1694
            ->method('get')
1695
            ->will($this->returnValue([]));
1696
        $request->query = $query;
1697
        $request->expects($this->any())
1698
            ->method('get')
1699
            ->will($this->returnValue($authorId));
1700
1701
        $commentAdmin->setRequest($request);
1702
1703
        $modelManager = $this->createMock(ModelManagerInterface::class);
1704
        $modelManager->expects($this->any())
1705
            ->method('getDefaultSortValues')
1706
            ->will($this->returnValue([]));
1707
1708
        $commentAdmin->setModelManager($modelManager);
1709
1710
        $parameters = $commentAdmin->getFilterParameters();
1711
1712
        $this->assertTrue(isset($parameters['post__author']));
1713
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1714
    }
1715
1716
    public function testGetFilterFieldDescription(): void
1717
    {
1718
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
1719
1720
        $fooFieldDescription = new FieldDescription();
1721
        $barFieldDescription = new FieldDescription();
1722
        $bazFieldDescription = new FieldDescription();
1723
1724
        $modelManager = $this->createMock(ModelManagerInterface::class);
1725
        $modelManager->expects($this->exactly(3))
1726
            ->method('getNewFieldDescriptionInstance')
1727
            ->will($this->returnCallback(function ($adminClass, $name, $filterOptions) use ($fooFieldDescription, $barFieldDescription, $bazFieldDescription) {
1728
                switch ($name) {
1729
                    case 'foo':
1730
                        $fieldDescription = $fooFieldDescription;
1731
1732
                        break;
1733
1734
                    case 'bar':
1735
                        $fieldDescription = $barFieldDescription;
1736
1737
                        break;
1738
1739
                    case 'baz':
1740
                        $fieldDescription = $bazFieldDescription;
1741
1742
                        break;
1743
1744
                    default:
1745
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1746
                        break;
1747
                }
1748
1749
                $fieldDescription->setName($name);
1750
1751
                return $fieldDescription;
1752
            }));
1753
1754
        $modelAdmin->setModelManager($modelManager);
1755
1756
        $pager = $this->createMock(PagerInterface::class);
1757
1758
        $datagrid = $this->createMock(DatagridInterface::class);
1759
        $datagrid->expects($this->once())
1760
            ->method('getPager')
1761
            ->will($this->returnValue($pager));
1762
1763
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1764
        $datagridBuilder->expects($this->once())
1765
            ->method('getBaseDatagrid')
1766
            ->with($this->identicalTo($modelAdmin), [])
1767
            ->will($this->returnValue($datagrid));
1768
1769
        $datagridBuilder->expects($this->exactly(3))
1770
            ->method('addFilter')
1771
            ->will($this->returnCallback(function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1772
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1773
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1774
            }));
1775
1776
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1777
1778
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1779
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1780
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1781
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1782
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1783
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1784
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1785
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1786
    }
1787
1788
    public function testGetSubjectNoRequest(): void
1789
    {
1790
        $modelManager = $this->createMock(ModelManagerInterface::class);
1791
        $modelManager
1792
            ->expects($this->never())
1793
            ->method('find');
1794
1795
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1796
        $admin->setModelManager($modelManager);
1797
1798
        $this->assertNull($admin->getSubject());
1799
    }
1800
1801
    public function testGetSideMenu(): void
1802
    {
1803
        $item = $this->createMock(ItemInterface::class);
1804
        $item
1805
            ->expects($this->once())
1806
            ->method('setChildrenAttribute')
1807
            ->with('class', 'nav navbar-nav');
1808
        $item
1809
            ->expects($this->once())
1810
            ->method('setExtra')
1811
            ->with('translation_domain', 'foo_bar_baz');
1812
1813
        $menuFactory = $this->createMock(FactoryInterface::class);
1814
        $menuFactory
1815
            ->expects($this->once())
1816
            ->method('createItem')
1817
            ->will($this->returnValue($item));
1818
1819
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
1820
        $modelAdmin->setMenuFactory($menuFactory);
1821
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1822
1823
        $modelAdmin->getSideMenu('foo');
1824
    }
1825
1826
    /**
1827
     * @return array
1828
     */
1829
    public function provideGetSubject()
1830
    {
1831
        return [
1832
            [23],
1833
            ['azerty'],
1834
            ['4f69bbb5f14a13347f000092'],
1835
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1836
            ['123'.AdapterInterface::ID_SEPARATOR.'my_type'], // composite keys are supported
1837
        ];
1838
    }
1839
1840
    /**
1841
     * @dataProvider provideGetSubject
1842
     */
1843
    public function testGetSubjectFailed($id): void
1844
    {
1845
        $modelManager = $this->createMock(ModelManagerInterface::class);
1846
        $modelManager
1847
            ->expects($this->once())
1848
            ->method('find')
1849
            ->with('NewsBundle\Entity\Post', $id)
1850
            ->will($this->returnValue(null)); // entity not found
1851
1852
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1853
        $admin->setModelManager($modelManager);
0 ignored issues
show
$modelManager is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Sonata\AdminBundl...\ModelManagerInterface>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1854
1855
        $admin->setRequest(new Request(['id' => $id]));
1856
        $this->assertNull($admin->getSubject());
1857
    }
1858
1859
    /**
1860
     * @dataProvider provideGetSubject
1861
     */
1862
    public function testGetSubject($id): void
1863
    {
1864
        $entity = new Post();
1865
1866
        $modelManager = $this->createMock(ModelManagerInterface::class);
1867
        $modelManager
1868
            ->expects($this->once())
1869
            ->method('find')
1870
            ->with('NewsBundle\Entity\Post', $id)
1871
            ->will($this->returnValue($entity));
1872
1873
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1874
        $admin->setModelManager($modelManager);
1875
1876
        $admin->setRequest(new Request(['id' => $id]));
1877
        $this->assertSame($entity, $admin->getSubject());
1878
        $this->assertSame($entity, $admin->getSubject()); // model manager must be used only once
1879
    }
1880
1881
    public function testGetSubjectWithParentDescription(): void
1882
    {
1883
        $adminId = 1;
1884
1885
        $comment = new Comment();
1886
1887
        $modelManager = $this->createMock(ModelManagerInterface::class);
1888
        $modelManager
1889
            ->expects($this->any())
1890
            ->method('find')
1891
            ->with('NewsBundle\Entity\Comment', $adminId)
1892
            ->will($this->returnValue($comment));
1893
1894
        $request = new Request(['id' => $adminId]);
1895
1896
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1897
        $postAdmin->setRequest($request);
1898
1899
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
1900
        $commentAdmin->setRequest($request);
1901
        $commentAdmin->setModelManager($modelManager);
1902
1903
        $this->assertSame($comment, $commentAdmin->getSubject());
1904
1905
        $commentAdmin->setSubject(null);
1906
        $commentAdmin->setParentFieldDescription(new FieldDescription());
1907
1908
        $this->assertNull($commentAdmin->getSubject());
1909
    }
1910
1911
    /**
1912
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1913
     */
1914
    public function testGetActionButtonsList(): void
1915
    {
1916
        $expected = [
1917
            'create' => [
1918
                'template' => 'Foo.html.twig',
1919
            ],
1920
        ];
1921
1922
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1923
1924
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1925
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
1926
1927
        $admin->setTemplateRegistry($templateRegistry->reveal());
1928
1929
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1930
        $securityHandler
1931
            ->expects($this->once())
1932
            ->method('isGranted')
1933
            ->with($admin, 'CREATE', $admin)
1934
            ->will($this->returnValue(true));
1935
        $admin->setSecurityHandler($securityHandler);
1936
1937
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1938
        $routeGenerator
1939
            ->expects($this->once())
1940
            ->method('hasAdminRoute')
1941
            ->with($admin, 'create')
1942
            ->will($this->returnValue(true));
1943
        $admin->setRouteGenerator($routeGenerator);
1944
1945
        $this->assertSame($expected, $admin->getActionButtons('list', null));
1946
    }
1947
1948
    /**
1949
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1950
     */
1951
    public function testGetActionButtonsListCreateDisabled(): void
1952
    {
1953
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1954
1955
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1956
        $securityHandler
1957
            ->expects($this->once())
1958
            ->method('isGranted')
1959
            ->with($admin, 'CREATE', $admin)
1960
            ->will($this->returnValue(false));
1961
        $admin->setSecurityHandler($securityHandler);
1962
1963
        $this->assertSame([], $admin->getActionButtons('list', null));
1964
    }
1965
1966
    /**
1967
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
1968
     */
1969
    public function testGetBatchActions(): void
1970
    {
1971
        $expected = [
1972
            'delete' => [
1973
                'label' => 'action_delete',
1974
                'translation_domain' => 'SonataAdminBundle',
1975
                'ask_confirmation' => true, // by default always true
1976
            ],
1977
            'foo' => [
1978
                'label' => 'action_foo',
1979
                'translation_domain' => 'SonataAdminBundle',
1980
            ],
1981
            'bar' => [
1982
                'label' => 'batch.label_bar',
1983
                'translation_domain' => 'SonataAdminBundle',
1984
            ],
1985
            'baz' => [
1986
                'label' => 'action_baz',
1987
                'translation_domain' => 'AcmeAdminBundle',
1988
            ],
1989
        ];
1990
1991
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
1992
1993
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1994
        $labelTranslatorStrategy->expects($this->any())
1995
            ->method('getLabel')
1996
            ->will($this->returnCallback(function ($label, $context = '', $type = '') {
1997
                return $context.'.'.$type.'_'.$label;
1998
            }));
1999
2000
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
2001
        $admin->setRouteBuilder($pathInfo);
2002
        $admin->setTranslationDomain('SonataAdminBundle');
2003
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
2004
2005
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2006
        $routeGenerator
2007
            ->expects($this->once())
2008
            ->method('hasAdminRoute')
2009
            ->with($admin, 'delete')
2010
            ->will($this->returnValue(true));
2011
        $admin->setRouteGenerator($routeGenerator);
2012
2013
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2014
        $securityHandler->expects($this->any())
2015
            ->method('isGranted')
2016
            ->will($this->returnCallback(function (AdminInterface $adminIn, $attributes, $object = null) use ($admin) {
2017
                if ($admin === $adminIn && 'DELETE' === $attributes) {
2018
                    return true;
2019
                }
2020
2021
                return false;
2022
            }));
2023
        $admin->setSecurityHandler($securityHandler);
2024
2025
        $this->assertSame($expected, $admin->getBatchActions());
2026
    }
2027
2028
    /**
2029
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2030
     */
2031
    public function testShowMosaicButton(): void
2032
    {
2033
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
2034
        $listModes = $admin->getListModes();
2035
2036
        $admin->showMosaicButton(true);
2037
2038
        $this->assertSame($listModes, $admin->getListModes());
2039
    }
2040
2041
    /**
2042
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2043
     */
2044
    public function testShowMosaicButtonHideMosaic(): void
2045
    {
2046
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
2047
        $listModes = $admin->getListModes();
2048
        $expected['list'] = $listModes['list'];
2049
2050
        $admin->showMosaicButton(false);
2051
2052
        $this->assertSame($expected, $admin->getListModes());
2053
    }
2054
2055
    /**
2056
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2057
     * @dataProvider provideGetBaseRouteName
2058
     */
2059
    public function testDefaultDashboardActionsArePresent($objFqn, $expected): void
2060
    {
2061
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2062
2063
        $routeGenerator = new DefaultRouteGenerator(
2064
            $this->createMock(RouterInterface::class),
2065
            new RoutesCache($this->cacheTempFolder, true)
2066
        );
2067
2068
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
2069
        $admin->setRouteBuilder($pathInfo);
2070
        $admin->setRouteGenerator($routeGenerator);
2071
        $admin->initialize();
2072
2073
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2074
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2075
2076
        $admin->setTemplateRegistry($templateRegistry->reveal());
2077
2078
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2079
        $securityHandler->expects($this->any())
2080
            ->method('isGranted')
2081
            ->will($this->returnCallback(function (AdminInterface $adminIn, $attributes, $object = null) use ($admin) {
2082
                if ($admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes)) {
2083
                    return true;
2084
                }
2085
2086
                return false;
2087
            }));
2088
2089
        $admin->setSecurityHandler($securityHandler);
2090
2091
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2092
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2093
    }
2094
2095
    public function testDefaultFilters(): void
2096
    {
2097
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
2098
2099
        $subjectId = uniqid();
2100
2101
        $request = $this->createMock(Request::class, ['get']);
2102
        $query = $this->createMock(ParameterBag::class, ['set', 'get']);
2103
        $query->expects($this->any())
2104
            ->method('get')
2105
            ->with($this->equalTo('filter'))
2106
            ->will($this->returnValue([
2107
                'a' => [
2108
                    'value' => 'b',
2109
                ],
2110
                'foo' => [
2111
                    'type' => '1',
2112
                    'value' => 'bar',
2113
                ],
2114
                'baz' => [
2115
                    'type' => '5',
2116
                    'value' => 'test',
2117
                ],
2118
            ]));
2119
        $request->query = $query;
2120
2121
        $request->expects($this->any())
2122
            ->method('get')
2123
            ->will($this->returnValue($subjectId));
2124
2125
        $admin->setRequest($request);
2126
2127
        $modelManager = $this->createMock(ModelManagerInterface::class);
2128
        $modelManager->expects($this->any())
2129
            ->method('getDefaultSortValues')
2130
            ->will($this->returnValue([]));
2131
2132
        $admin->setModelManager($modelManager);
2133
2134
        $this->assertSame([
2135
            '_page' => 1,
2136
            '_per_page' => 32,
2137
            'foo' => [
2138
                'type' => '1',
2139
                'value' => 'bar',
2140
            ],
2141
            'baz' => [
2142
                'type' => '5',
2143
                'value' => 'test',
2144
            ],
2145
            'a' => [
2146
                'value' => 'b',
2147
            ],
2148
        ], $admin->getFilterParameters());
2149
2150
        $this->assertTrue($admin->isDefaultFilter('foo'));
2151
        $this->assertFalse($admin->isDefaultFilter('bar'));
2152
        $this->assertFalse($admin->isDefaultFilter('a'));
2153
    }
2154
2155
    /**
2156
     * @group legacy
2157
     */
2158
    public function testDefaultBreadcrumbsBuilder(): void
2159
    {
2160
        $container = $this->createMock(ContainerInterface::class);
2161
        $container->expects($this->once())
2162
            ->method('getParameter')
2163
            ->with('sonata.admin.configuration.breadcrumbs')
2164
            ->will($this->returnValue([]));
2165
2166
        $pool = $this->getMockBuilder(Pool::class)
2167
            ->disableOriginalConstructor()
2168
            ->getMock();
2169
        $pool->expects($this->once())
2170
            ->method('getContainer')
2171
            ->will($this->returnValue($container));
2172
2173
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2174
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2175
        ], '', true, true, true, ['getConfigurationPool']);
2176
        $admin->expects($this->once())
2177
            ->method('getConfigurationPool')
2178
            ->will($this->returnValue($pool));
2179
2180
        $this->assertInstanceOf(BreadcrumbsBuilder::class, $admin->getBreadcrumbsBuilder());
2181
    }
2182
2183
    /**
2184
     * @group legacy
2185
     */
2186
    public function testBreadcrumbsBuilderSetter(): void
2187
    {
2188
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2189
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2190
        ]);
2191
        $this->assertSame($admin, $admin->setBreadcrumbsBuilder($builder = $this->createMock(
2192
            BreadcrumbsBuilderInterface::class
2193
        )));
2194
        $this->assertSame($builder, $admin->getBreadcrumbsBuilder());
2195
    }
2196
2197
    /**
2198
     * @group legacy
2199
     */
2200
    public function testGetBreadcrumbs(): void
2201
    {
2202
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2203
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2204
        ]);
2205
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2206
        $action = 'myaction';
2207
        $builder->getBreadcrumbs($admin, $action)->shouldBeCalled();
2208
        $admin->setBreadcrumbsBuilder($builder->reveal())->getBreadcrumbs($action);
2209
    }
2210
2211
    /**
2212
     * @group legacy
2213
     */
2214
    public function testBuildBreadcrumbs(): void
2215
    {
2216
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2217
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2218
        ]);
2219
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2220
        $action = 'myaction';
2221
        $menu = $this->createMock(ItemInterface::class);
2222
        $builder->buildBreadcrumbs($admin, $action, $menu)
2223
            ->shouldBeCalledTimes(1)
2224
            ->willReturn($menu);
2225
        $admin->setBreadcrumbsBuilder($builder->reveal());
2226
2227
        /* check the called is proxied only once */
2228
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2229
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2230
    }
2231
2232
    /**
2233
     * NEXT_MAJOR: remove this method.
2234
     *
2235
     * @group legacy
2236
     */
2237
    public function testCreateQueryLegacyCallWorks(): void
2238
    {
2239
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2240
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2241
        ]);
2242
        $modelManager = $this->createMock(ModelManagerInterface::class);
2243
        $modelManager->expects($this->once())
2244
            ->method('createQuery')
2245
            ->with('My\Class')
2246
            ->willReturn('a query');
2247
2248
        $admin->setModelManager($modelManager);
2249
        $this->assertSame('a query', $admin->createQuery('list'));
2250
    }
2251
2252
    public function testGetDataSourceIterator(): void
2253
    {
2254
        $datagrid = $this->createMock(DatagridInterface::class);
2255
        $datagrid->method('buildPager');
2256
2257
        $modelManager = $this->createMock(ModelManagerInterface::class);
2258
        $modelManager->method('getExportFields')->will($this->returnValue([
2259
            'field',
2260
            'foo',
2261
            'bar',
2262
        ]));
2263
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2264
            ->with($this->equalTo($datagrid), $this->equalTo([
2265
                'Feld' => 'field',
2266
                1 => 'foo',
2267
                2 => 'bar',
2268
            ]));
2269
2270
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2271
            ->disableOriginalConstructor()
2272
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2273
            ->getMockForAbstractClass();
2274
        $admin->method('getDatagrid')->will($this->returnValue($datagrid));
2275
        $admin->setModelManager($modelManager);
2276
2277
        $admin->expects($this->any())
2278
            ->method('getTranslationLabel')
2279
            ->will($this->returnCallback(function ($label, $context = '', $type = '') {
2280
                return $context.'.'.$type.'_'.$label;
2281
            }));
2282
        $admin->expects($this->any())
2283
            ->method('trans')
2284
            ->will($this->returnCallback(function ($label) {
2285
                if ('export.label_field' === $label) {
2286
                    return 'Feld';
2287
                }
2288
2289
                return $label;
2290
            }));
2291
2292
        $admin->getDataSourceIterator();
2293
    }
2294
2295
    public function testCircularChildAdmin(): void
2296
    {
2297
        $this->expectException(
2298
            \RuntimeException::class,
2299
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2300
        );
2301
2302
        $postAdmin = new PostAdmin(
2303
            'sonata.post.admin.post',
2304
            'Application\Sonata\NewsBundle\Entity\Post',
2305
            'SonataNewsBundle:PostAdmin'
2306
        );
2307
        $commentAdmin = new CommentAdmin(
2308
            'sonata.post.admin.comment',
2309
            'Application\Sonata\NewsBundle\Entity\Comment',
2310
            'SonataNewsBundle:CommentAdmin'
2311
        );
2312
        $postAdmin->addChild($commentAdmin, 'post');
2313
        $commentAdmin->addChild($postAdmin, 'comment');
2314
    }
2315
2316
    public function testCircularChildAdminTripleLevel(): void
2317
    {
2318
        $this->expectException(
2319
            \RuntimeException::class,
2320
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2321
        );
2322
2323
        $postAdmin = new PostAdmin(
2324
            'sonata.post.admin.post',
2325
            'Application\Sonata\NewsBundle\Entity\Post',
2326
            'SonataNewsBundle:PostAdmin'
2327
        );
2328
        $commentAdmin = new CommentAdmin(
2329
            'sonata.post.admin.comment',
2330
            'Application\Sonata\NewsBundle\Entity\Comment',
2331
            'SonataNewsBundle:CommentAdmin'
2332
        );
2333
        $commentVoteAdmin = new CommentVoteAdmin(
2334
            'sonata.post.admin.comment_vote',
2335
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2336
            'SonataNewsBundle:CommentVoteAdmin'
2337
        );
2338
        $postAdmin->addChild($commentAdmin, 'post');
2339
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2340
        $commentVoteAdmin->addChild($postAdmin, 'post');
2341
    }
2342
2343
    public function testCircularChildAdminWithItself(): void
2344
    {
2345
        $this->expectException(
2346
            \RuntimeException::class,
2347
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2348
        );
2349
2350
        $postAdmin = new PostAdmin(
2351
            'sonata.post.admin.post',
2352
            'Application\Sonata\NewsBundle\Entity\Post',
2353
            'SonataNewsBundle:PostAdmin'
2354
        );
2355
        $postAdmin->addChild($postAdmin);
2356
    }
2357
2358
    public function testGetRootAncestor(): void
2359
    {
2360
        $postAdmin = new PostAdmin(
2361
            'sonata.post.admin.post',
2362
            'Application\Sonata\NewsBundle\Entity\Post',
2363
            'SonataNewsBundle:PostAdmin'
2364
        );
2365
        $commentAdmin = new CommentAdmin(
2366
            'sonata.post.admin.comment',
2367
            'Application\Sonata\NewsBundle\Entity\Comment',
2368
            'SonataNewsBundle:CommentAdmin'
2369
        );
2370
        $commentVoteAdmin = new CommentVoteAdmin(
2371
            'sonata.post.admin.comment_vote',
2372
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2373
            'SonataNewsBundle:CommentVoteAdmin'
2374
        );
2375
2376
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2377
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2378
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2379
2380
        $postAdmin->addChild($commentAdmin, 'post');
2381
2382
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2383
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2384
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2385
2386
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2387
2388
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2389
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2390
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2391
    }
2392
2393
    public function testGetChildDepth(): void
2394
    {
2395
        $postAdmin = new PostAdmin(
2396
            'sonata.post.admin.post',
2397
            'Application\Sonata\NewsBundle\Entity\Post',
2398
            'SonataNewsBundle:PostAdmin'
2399
        );
2400
        $commentAdmin = new CommentAdmin(
2401
            'sonata.post.admin.comment',
2402
            'Application\Sonata\NewsBundle\Entity\Comment',
2403
            'SonataNewsBundle:CommentAdmin'
2404
        );
2405
        $commentVoteAdmin = new CommentVoteAdmin(
2406
            'sonata.post.admin.comment_vote',
2407
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2408
            'SonataNewsBundle:CommentVoteAdmin'
2409
        );
2410
2411
        $this->assertSame(0, $postAdmin->getChildDepth());
2412
        $this->assertSame(0, $commentAdmin->getChildDepth());
2413
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2414
2415
        $postAdmin->addChild($commentAdmin, 'post');
2416
2417
        $this->assertSame(0, $postAdmin->getChildDepth());
2418
        $this->assertSame(1, $commentAdmin->getChildDepth());
2419
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2420
2421
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2422
2423
        $this->assertSame(0, $postAdmin->getChildDepth());
2424
        $this->assertSame(1, $commentAdmin->getChildDepth());
2425
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2426
    }
2427
2428
    public function testGetCurrentLeafChildAdmin(): void
2429
    {
2430
        $postAdmin = new PostAdmin(
2431
            'sonata.post.admin.post',
2432
            'Application\Sonata\NewsBundle\Entity\Post',
2433
            'SonataNewsBundle:PostAdmin'
2434
        );
2435
        $commentAdmin = new CommentAdmin(
2436
            'sonata.post.admin.comment',
2437
            'Application\Sonata\NewsBundle\Entity\Comment',
2438
            'SonataNewsBundle:CommentAdmin'
2439
        );
2440
        $commentVoteAdmin = new CommentVoteAdmin(
2441
            'sonata.post.admin.comment_vote',
2442
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2443
            'SonataNewsBundle:CommentVoteAdmin'
2444
        );
2445
2446
        $postAdmin->addChild($commentAdmin, 'post');
2447
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2448
2449
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2450
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2451
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2452
2453
        $commentAdmin->setCurrentChild(true);
2454
2455
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2456
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2457
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2458
2459
        $commentVoteAdmin->setCurrentChild(true);
2460
2461
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2462
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2463
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2464
    }
2465
2466
    private function createTagAdmin(Post $post): TagAdmin
2467
    {
2468
        $postAdmin = $this->getMockBuilder(PostAdmin::class)
2469
            ->disableOriginalConstructor()
2470
            ->getMock();
2471
2472
        $postAdmin->expects($this->any())->method('getObject')->will($this->returnValue($post));
2473
2474
        $formBuilder = $this->createMock(FormBuilderInterface::class);
2475
        $formBuilder->expects($this->any())->method('getForm')->will($this->returnValue(null));
2476
2477
        $tagAdmin = $this->getMockBuilder(TagAdmin::class)
2478
            ->setConstructorArgs([
2479
                'admin.tag',
2480
                Tag::class,
2481
                'MyBundle:MyController',
2482
            ])
2483
            ->setMethods(['getFormBuilder'])
2484
            ->getMock();
2485
2486
        $tagAdmin->expects($this->any())->method('getFormBuilder')->will($this->returnValue($formBuilder));
2487
        $tagAdmin->setParent($postAdmin);
2488
2489
        $tag = new Tag();
2490
        $tagAdmin->setSubject($tag);
2491
2492
        $request = $this->createMock(Request::class);
2493
        $tagAdmin->setRequest($request);
2494
2495
        $configurationPool = $this->getMockBuilder(Pool::class)
2496
            ->disableOriginalConstructor()
2497
            ->getMock();
2498
2499
        $configurationPool->expects($this->any())->method('getPropertyAccessor')->will($this->returnValue(PropertyAccess::createPropertyAccessor()));
2500
2501
        $tagAdmin->setConfigurationPool($configurationPool);
2502
2503
        return $tagAdmin;
2504
    }
2505
}
2506