Completed
Push — master ( a97f84...b5df1f )
by
unknown
11:58
created

tests/Admin/AdminTest.php (2 issues)

Upgrade to new PHP Analysis Engine

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

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