Completed
Pull Request — master (#6210)
by Jordi Sala
03:31
created

AdminTest::testGetRootAncestor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
608
    }
609
610
    public function testIsAclEnabled(): void
611
    {
612
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
613
614
        $this->assertFalse($postAdmin->isAclEnabled());
615
616
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
617
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
618
        $this->assertTrue($commentAdmin->isAclEnabled());
619
    }
620
621
    /**
622
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
623
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
624
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
625
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
626
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
627
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
628
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
629
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
630
     */
631
    public function testSubClass(): void
632
    {
633
        $admin = new PostAdmin(
634
            'sonata.post.admin.post',
635
            Post::class,
636
            'Sonata\NewsBundle\Controller\PostAdminController'
637
        );
638
        $this->assertFalse($admin->hasSubClass('test'));
639
        $this->assertFalse($admin->hasActiveSubClass());
640
        $this->assertCount(0, $admin->getSubClasses());
641
        $this->assertSame(Post::class, $admin->getClass());
642
643
        // Just for the record, if there is no inheritance set, the getSubject is not used
644
        // the getSubject can also lead to some issue
645
        $admin->setSubject(new BlogPost());
646
        $this->assertSame(BlogPost::class, $admin->getClass());
647
648
        $admin->setSubClasses([
649
            'extended1' => 'NewsBundle\Entity\PostExtended1',
650
            'extended2' => 'NewsBundle\Entity\PostExtended2',
651
        ]);
652
        $this->assertFalse($admin->hasSubClass('test'));
653
        $this->assertTrue($admin->hasSubClass('extended1'));
654
        $this->assertFalse($admin->hasActiveSubClass());
655
        $this->assertCount(2, $admin->getSubClasses());
656
        $this->assertSame(
657
            BlogPost::class,
658
            $admin->getClass(),
659
            'When there is no subclass in the query the class parameter should be returned'
660
        );
661
662
        $request = new Request(['subclass' => 'extended1']);
663
        $admin->setRequest($request);
664
        $this->assertFalse($admin->hasSubClass('test'));
665
        $this->assertTrue($admin->hasSubClass('extended1'));
666
        $this->assertTrue($admin->hasActiveSubClass());
667
        $this->assertCount(2, $admin->getSubClasses());
668
        $this->assertSame(
669
            'NewsBundle\Entity\PostExtended1',
670
            $admin->getActiveSubClass(),
671
            'It should return the curently active sub class.'
672
        );
673
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
674
        $this->assertSame(
675
            'NewsBundle\Entity\PostExtended1',
676
            $admin->getClass(),
677
            'getClass() should return the name of the sub class when passed through a request query parameter.'
678
        );
679
680
        $request->query->set('subclass', 'inject');
681
682
        $this->expectException(\LogicException::class);
683
        $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
684
685
        $admin->getActiveSubclassCode();
686
    }
687
688
    public function testNonExistantSubclass(): void
689
    {
690
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
691
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
692
693
        $admin->setRequest(new Request(['subclass' => 'inject']));
694
695
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
696
697
        $this->assertTrue($admin->hasActiveSubClass());
698
699
        $this->expectException(\LogicException::class);
700
701
        $admin->getActiveSubClass();
702
    }
703
704
    /**
705
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
706
     */
707
    public function testOnlyOneSubclassNeededToBeActive(): void
708
    {
709
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
710
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
711
        $request = new Request(['subclass' => 'extended1']);
712
        $admin->setRequest($request);
713
        $this->assertTrue($admin->hasActiveSubClass());
714
    }
715
716
    public function testGetLabelTranslatorStrategy(): void
717
    {
718
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
719
720
        $this->assertNull($admin->getLabelTranslatorStrategy());
721
722
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
723
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
724
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
725
    }
726
727
    public function testGetRouteBuilder(): void
728
    {
729
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
730
731
        $this->assertNull($admin->getRouteBuilder());
732
733
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
734
        $admin->setRouteBuilder($routeBuilder);
735
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
736
    }
737
738
    public function testGetMenuFactory(): void
739
    {
740
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
741
742
        $this->assertNull($admin->getMenuFactory());
743
744
        $menuFactory = $this->createMock(FactoryInterface::class);
745
        $admin->setMenuFactory($menuFactory);
746
        $this->assertSame($menuFactory, $admin->getMenuFactory());
747
    }
748
749
    public function testGetExtensions(): void
750
    {
751
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
752
753
        $this->assertSame([], $admin->getExtensions());
754
755
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
756
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
757
758
        $admin->addExtension($adminExtension1);
759
        $admin->addExtension($adminExtension2);
760
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
761
    }
762
763
    public function testGetFilterTheme(): void
764
    {
765
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
766
767
        $this->assertSame([], $admin->getFilterTheme());
768
769
        $admin->setFilterTheme(['FooTheme']);
770
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
771
    }
772
773
    public function testGetFormTheme(): void
774
    {
775
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
776
777
        $this->assertSame([], $admin->getFormTheme());
778
779
        $admin->setFormTheme(['FooTheme']);
780
781
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
782
    }
783
784
    public function testGetValidator(): void
785
    {
786
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
787
788
        $this->assertNull($admin->getValidator());
789
790
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
791
792
        $admin->setValidator($validator);
793
        $this->assertSame($validator, $admin->getValidator());
794
    }
795
796
    public function testGetSecurityHandler(): void
797
    {
798
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
799
800
        $this->assertNull($admin->getSecurityHandler());
801
802
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
803
        $admin->setSecurityHandler($securityHandler);
804
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
805
    }
806
807
    public function testGetSecurityInformation(): void
808
    {
809
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
810
811
        $this->assertSame([], $admin->getSecurityInformation());
812
813
        $securityInformation = [
814
            'GUEST' => ['VIEW', 'LIST'],
815
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
816
        ];
817
818
        $admin->setSecurityInformation($securityInformation);
819
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
820
    }
821
822
    public function testGetManagerType(): void
823
    {
824
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
825
826
        $this->assertNull($admin->getManagerType());
827
828
        $admin->setManagerType('foo_orm');
829
        $this->assertSame('foo_orm', $admin->getManagerType());
830
    }
831
832
    public function testGetModelManager(): void
833
    {
834
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
835
836
        $this->assertNull($admin->getModelManager());
837
838
        $modelManager = $this->createMock(ModelManagerInterface::class);
839
840
        $admin->setModelManager($modelManager);
841
        $this->assertSame($modelManager, $admin->getModelManager());
842
    }
843
844
    public function testGetBaseCodeRoute(): void
845
    {
846
        $postAdmin = new PostAdmin(
847
            'sonata.post.admin.post',
848
            'NewsBundle\Entity\Post',
849
            'Sonata\NewsBundle\Controller\PostAdminController'
850
        );
851
        $commentAdmin = new CommentAdmin(
852
            'sonata.post.admin.comment',
853
            'Application\Sonata\NewsBundle\Entity\Comment',
854
            'Sonata\NewsBundle\Controller\CommentAdminController'
855
        );
856
857
        $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
858
859
        $postAdmin->addChild($commentAdmin, 'post');
860
861
        $this->assertSame(
862
            'sonata.post.admin.post|sonata.post.admin.comment',
863
            $commentAdmin->getBaseCodeRoute()
864
        );
865
    }
866
867
    public function testGetRouteGenerator(): void
868
    {
869
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
870
871
        $this->assertNull($admin->getRouteGenerator());
872
873
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
874
875
        $admin->setRouteGenerator($routeGenerator);
876
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
877
    }
878
879
    public function testGetConfigurationPool(): void
880
    {
881
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
882
883
        $this->assertNull($admin->getConfigurationPool());
884
885
        $pool = $this->getMockBuilder(Pool::class)
886
            ->disableOriginalConstructor()
887
            ->getMock();
888
889
        $admin->setConfigurationPool($pool);
890
        $this->assertSame($pool, $admin->getConfigurationPool());
891
    }
892
893
    public function testGetShowBuilder(): void
894
    {
895
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
896
897
        $this->assertNull($admin->getShowBuilder());
898
899
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
900
901
        $admin->setShowBuilder($showBuilder);
902
        $this->assertSame($showBuilder, $admin->getShowBuilder());
903
    }
904
905
    public function testGetListBuilder(): void
906
    {
907
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
908
909
        $this->assertNull($admin->getListBuilder());
910
911
        $listBuilder = $this->createMock(ListBuilderInterface::class);
912
913
        $admin->setListBuilder($listBuilder);
914
        $this->assertSame($listBuilder, $admin->getListBuilder());
915
    }
916
917
    public function testGetDatagridBuilder(): void
918
    {
919
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
920
921
        $this->assertNull($admin->getDatagridBuilder());
922
923
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
924
925
        $admin->setDatagridBuilder($datagridBuilder);
926
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
927
    }
928
929
    public function testGetFormContractor(): void
930
    {
931
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
932
933
        $this->assertNull($admin->getFormContractor());
934
935
        $formContractor = $this->createMock(FormContractorInterface::class);
936
937
        $admin->setFormContractor($formContractor);
938
        $this->assertSame($formContractor, $admin->getFormContractor());
939
    }
940
941
    public function testGetRequest(): void
942
    {
943
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
944
945
        $this->assertFalse($admin->hasRequest());
946
947
        $request = new Request();
948
949
        $admin->setRequest($request);
950
        $this->assertSame($request, $admin->getRequest());
951
        $this->assertTrue($admin->hasRequest());
952
    }
953
954
    public function testGetRequestWithException(): void
955
    {
956
        $this->expectException(\LogicException::class);
957
        $this->expectExceptionMessage('The Request object has not been set');
958
959
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
960
        $admin->getRequest();
961
    }
962
963
    public function testGetTranslationDomain(): void
964
    {
965
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
966
967
        $this->assertSame('messages', $admin->getTranslationDomain());
968
969
        $admin->setTranslationDomain('foo');
970
        $this->assertSame('foo', $admin->getTranslationDomain());
971
    }
972
973
    public function testGetShowGroups(): void
974
    {
975
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
976
977
        $this->assertSame([], $admin->getShowGroups());
978
979
        $groups = ['foo', 'bar', 'baz'];
980
981
        $admin->setShowGroups($groups);
982
        $this->assertSame($groups, $admin->getShowGroups());
983
    }
984
985
    public function testGetFormGroups(): void
986
    {
987
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
988
989
        $this->assertSame([], $admin->getFormGroups());
990
991
        $groups = ['foo', 'bar', 'baz'];
992
993
        $admin->setFormGroups($groups);
994
        $this->assertSame($groups, $admin->getFormGroups());
995
    }
996
997
    public function testGetMaxPageLinks(): void
998
    {
999
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1000
1001
        $this->assertSame(25, $admin->getMaxPageLinks());
1002
1003
        $admin->setMaxPageLinks(14);
1004
        $this->assertSame(14, $admin->getMaxPageLinks());
1005
    }
1006
1007
    public function testGetLabel(): void
1008
    {
1009
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1010
1011
        $this->assertNull($admin->getLabel());
1012
1013
        $admin->setLabel('FooLabel');
1014
        $this->assertSame('FooLabel', $admin->getLabel());
1015
    }
1016
1017
    public function testGetBaseController(): void
1018
    {
1019
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1020
1021
        $this->assertSame('Sonata\NewsBundle\Controller\PostAdminController', $admin->getBaseControllerName());
1022
1023
        $admin->setBaseControllerName('Sonata\NewsBundle\Controller\FooAdminController');
1024
        $this->assertSame('Sonata\NewsBundle\Controller\FooAdminController', $admin->getBaseControllerName());
1025
    }
1026
1027
    public function testGetIdParameter(): void
1028
    {
1029
        $postAdmin = new PostAdmin(
1030
            'sonata.post.admin.post',
1031
            'NewsBundle\Entity\Post',
1032
            'Sonata\NewsBundle\Controller\PostAdminController'
1033
        );
1034
1035
        $this->assertSame('id', $postAdmin->getIdParameter());
1036
        $this->assertFalse($postAdmin->isChild());
1037
1038
        $commentAdmin = new CommentAdmin(
1039
            'sonata.post.admin.comment',
1040
            'Application\Sonata\NewsBundle\Entity\Comment',
1041
            'Sonata\NewsBundle\Controller\CommentAdminController'
1042
        );
1043
        $commentAdmin->setParent($postAdmin);
1044
1045
        $this->assertTrue($commentAdmin->isChild());
1046
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1047
1048
        $commentVoteAdmin = new CommentVoteAdmin(
1049
            'sonata.post.admin.comment_vote',
1050
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1051
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
1052
        );
1053
        $commentVoteAdmin->setParent($commentAdmin);
1054
1055
        $this->assertTrue($commentVoteAdmin->isChild());
1056
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1057
    }
1058
1059
    public function testGetExportFormats(): void
1060
    {
1061
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1062
1063
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1064
    }
1065
1066
    public function testGetUrlsafeIdentifier(): void
1067
    {
1068
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1069
1070
        $model = new \stdClass();
1071
1072
        $modelManager = $this->createMock(ModelManagerInterface::class);
1073
        $modelManager->expects($this->once())
1074
            ->method('getUrlSafeIdentifier')
1075
            ->with($this->equalTo($model))
1076
            ->willReturn('foo');
1077
        $admin->setModelManager($modelManager);
1078
1079
        $this->assertSame('foo', $admin->getUrlSafeIdentifier($model));
1080
    }
1081
1082
    public function testDeterminedPerPageValue(): void
1083
    {
1084
        $modelManager = $this->createStub(ModelManagerInterface::class);
1085
1086
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1087
        $admin->setModelManager($modelManager);
1088
1089
        $this->assertFalse($admin->determinedPerPageValue(123));
1090
        $this->assertTrue($admin->determinedPerPageValue(25));
1091
    }
1092
1093
    public function testIsGranted(): void
1094
    {
1095
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1096
        $modelManager = $this->createStub(ModelManagerInterface::class);
1097
        $modelManager
1098
            ->method('getNormalizedIdentifier')
1099
            ->willReturnCallback(static function (?object $model = null): ?string {
1100
                return $model ? $model->id : null;
1101
            });
1102
1103
        $admin->setModelManager($modelManager);
1104
1105
        $entity1 = new \stdClass();
1106
        $entity1->id = '1';
1107
1108
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1109
        $securityHandler
1110
            ->expects($this->exactly(6))
1111
            ->method('isGranted')
1112
            ->willReturnCallback(static function (
1113
                AdminInterface $adminIn,
1114
                string $attributes,
1115
                ?object $object = null
1116
            ) use (
1117
                $admin,
1118
                $entity1
1119
            ): bool {
1120
                return $admin === $adminIn && 'FOO' === $attributes &&
1121
                    ($object === $admin || $object === $entity1);
1122
            });
1123
1124
        $admin->setSecurityHandler($securityHandler);
1125
1126
        $this->assertTrue($admin->isGranted('FOO'));
1127
        $this->assertTrue($admin->isGranted('FOO'));
1128
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1129
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1130
        $this->assertFalse($admin->isGranted('BAR'));
1131
        $this->assertFalse($admin->isGranted('BAR'));
1132
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1133
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1134
1135
        $entity2 = new \stdClass();
1136
        $entity2->id = '2';
1137
1138
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1139
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1140
1141
        $entity3 = new \stdClass();
1142
        $entity3->id = '3';
1143
1144
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1145
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1146
    }
1147
1148
    public function testSupportsPreviewMode(): void
1149
    {
1150
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1151
1152
        $this->assertFalse($admin->supportsPreviewMode());
1153
    }
1154
1155
    public function testGetPermissionsShow(): void
1156
    {
1157
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1158
1159
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1160
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1161
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1162
    }
1163
1164
    public function testShowIn(): void
1165
    {
1166
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1167
1168
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1169
        $securityHandler
1170
            ->method('isGranted')
1171
            ->willReturnCallback(static function (AdminInterface $adminIn, array $attributes, $object = null) use ($admin): bool {
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

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

Loading history...
1172
                return $admin === $adminIn && $attributes === ['LIST'];
1173
            });
1174
1175
        $admin->setSecurityHandler($securityHandler);
1176
1177
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1178
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1179
        $this->assertTrue($admin->showIn('foo'));
1180
    }
1181
1182
    public function testGetObjectIdentifier(): void
1183
    {
1184
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1185
1186
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1187
    }
1188
1189
    /**
1190
     * @doesNotPerformAssertions
1191
     */
1192
    public function testSetFilterPersister(): void
1193
    {
1194
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController');
1195
1196
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1197
1198
        $admin->setFilterPersister($filterPersister);
1199
    }
1200
1201
    public function testGetRootCode(): void
1202
    {
1203
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1204
1205
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1206
1207
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1208
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1209
        $parentFieldDescription->expects($this->once())
1210
            ->method('getAdmin')
1211
            ->willReturn($parentAdmin);
1212
1213
        $this->assertFalse($admin->hasParentFieldDescription());
1214
        $admin->setParentFieldDescription($parentFieldDescription);
1215
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1216
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1217
    }
1218
1219
    public function testGetRoot(): void
1220
    {
1221
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1222
1223
        $this->assertSame($admin, $admin->getRoot());
1224
1225
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1226
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1227
        $parentFieldDescription->expects($this->once())
1228
            ->method('getAdmin')
1229
            ->willReturn($parentAdmin);
1230
1231
        $this->assertFalse($admin->hasParentFieldDescription());
1232
        $admin->setParentFieldDescription($parentFieldDescription);
1233
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1234
        $this->assertSame($parentAdmin, $admin->getRoot());
1235
    }
1236
1237
    public function testGetExportFields(): void
1238
    {
1239
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1240
1241
        $modelManager = $this->createMock(ModelManagerInterface::class);
1242
        $modelManager->expects($this->once())
1243
            ->method('getExportFields')
1244
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1245
            ->willReturn(['foo', 'bar']);
1246
1247
        $admin->setModelManager($modelManager);
1248
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1249
    }
1250
1251
    public function testGetPersistentParametersWithNoExtension(): void
1252
    {
1253
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1254
1255
        $this->assertEmpty($admin->getPersistentParameters());
1256
    }
1257
1258
    public function testGetPersistentParametersWithValidExtension(): void
1259
    {
1260
        $expected = [
1261
            'context' => 'foobar',
1262
        ];
1263
1264
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1265
1266
        $extension = $this->createMock(AdminExtensionInterface::class);
1267
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1268
1269
        $admin->addExtension($extension);
1270
1271
        $this->assertSame($expected, $admin->getPersistentParameters());
1272
    }
1273
1274
    public function testGetNewInstanceForChildAdminWithParentValue(): void
1275
    {
1276
        $post = new Post();
1277
1278
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1279
        $postAdmin->method('getObject')->willReturn($post);
1280
1281
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1282
        $formBuilder->method('getForm')->willReturn(null);
1283
1284
        $tag = new Tag();
1285
1286
        $modelManager = $this->createStub(ModelManagerInterface::class);
1287
        $modelManager->method('getModelInstance')->willReturn($tag);
1288
1289
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1290
        $tagAdmin->setModelManager($modelManager);
1291
        $tagAdmin->setParent($postAdmin);
1292
1293
        $request = $this->createStub(Request::class);
1294
        $tagAdmin->setRequest($request);
1295
1296
        $configurationPool = $this->getMockBuilder(Pool::class)
1297
            ->disableOriginalConstructor()
1298
            ->getMock();
1299
1300
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1301
1302
        $tagAdmin->setConfigurationPool($configurationPool);
1303
1304
        $tag = $tagAdmin->getNewInstance();
1305
1306
        $this->assertSame($post, $tag->getPost());
1307
    }
1308
1309
    public function testGetNewInstanceForChildAdminWithCollectionParentValue(): void
1310
    {
1311
        $post = new Post();
1312
1313
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1314
        $postAdmin->method('getObject')->willReturn($post);
1315
1316
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1317
        $formBuilder->method('getForm')->willReturn(null);
1318
1319
        $postCategory = new PostCategory();
1320
1321
        $modelManager = $this->createStub(ModelManagerInterface::class);
1322
        $modelManager->method('getModelInstance')->willReturn($postCategory);
1323
1324
        $postCategoryAdmin = new PostCategoryAdmin('admin.post_category', PostCategoryAdmin::class, 'MyBundle\MyController');
1325
        $postCategoryAdmin->setModelManager($modelManager);
1326
        $postCategoryAdmin->setParent($postAdmin);
1327
1328
        $request = $this->createStub(Request::class);
1329
        $postCategoryAdmin->setRequest($request);
1330
1331
        $configurationPool = $this->getMockBuilder(Pool::class)
1332
            ->disableOriginalConstructor()
1333
            ->getMock();
1334
1335
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1336
1337
        $postCategoryAdmin->setConfigurationPool($configurationPool);
1338
1339
        $postCategory = $postCategoryAdmin->getNewInstance();
1340
1341
        $this->assertInstanceOf(Collection::class, $postCategory->getPosts());
1342
        $this->assertCount(1, $postCategory->getPosts());
1343
        $this->assertContains($post, $postCategory->getPosts());
1344
    }
1345
1346
    public function testGetNewInstanceForEmbededAdminWithParentValue(): void
1347
    {
1348
        $post = new Post();
1349
1350
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1351
        $postAdmin->method('getObject')->willReturn($post);
1352
1353
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1354
        $formBuilder->method('getForm')->willReturn(null);
1355
1356
        $parentField = $this->createStub(FieldDescriptionInterface::class);
1357
        $parentField->method('getAdmin')->willReturn($postAdmin);
1358
        $parentField->method('getParentAssociationMappings')->willReturn([]);
1359
        $parentField->method('getAssociationMapping')->willReturn(['fieldName' => 'tag', 'mappedBy' => 'post']);
1360
1361
        $tag = new Tag();
1362
1363
        $modelManager = $this->createStub(ModelManagerInterface::class);
1364
        $modelManager->method('getModelInstance')->willReturn($tag);
1365
1366
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1367
        $tagAdmin->setModelManager($modelManager);
1368
        $tagAdmin->setParentFieldDescription($parentField);
1369
1370
        $request = $this->createStub(Request::class);
1371
        $tagAdmin->setRequest($request);
1372
1373
        $configurationPool = $this->getMockBuilder(Pool::class)
1374
            ->disableOriginalConstructor()
1375
            ->getMock();
1376
1377
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1378
1379
        $tagAdmin->setConfigurationPool($configurationPool);
1380
1381
        $tag = $tagAdmin->getNewInstance();
1382
1383
        $this->assertSame($post, $tag->getPost());
1384
    }
1385
1386
    public function testFormAddPostSubmitEventForPreValidation(): void
1387
    {
1388
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1389
        $object = new \stdClass();
1390
1391
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1392
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1393
1394
        $validator = $this->createMock(ValidatorInterface::class);
1395
        $validator
1396
                ->method('getMetadataFor')
1397
                ->willReturn($this->createMock(MemberMetadata::class));
1398
        $modelAdmin->setValidator($validator);
1399
1400
        $modelManager = $this->createMock(ModelManagerInterface::class);
1401
        $modelManager
1402
            ->method('getNewFieldDescriptionInstance')
1403
            ->willReturn(new FieldDescription());
1404
        $modelAdmin->setModelManager($modelManager);
1405
1406
        // a Admin class to test that preValidate is called
1407
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1408
        $testAdminPreValidate->expects($this->once())
1409
                ->method('preValidate')
1410
                ->with($this->identicalTo($object));
1411
1412
        $event = $this->createMock(FormEvent::class);
1413
        $event
1414
                ->method('getData')
1415
                ->willReturn($object);
1416
1417
        $formBuild = $this->createMock(FormBuilder::class);
1418
        $formBuild->expects($this->once())
1419
                ->method('addEventListener')
1420
                ->with(
1421
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1422
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1423
                        if (\is_callable($callback)) {
1424
                            $closure = $callback->bindTo($testAdminPreValidate);
0 ignored issues
show
Bug introduced by
The method bindTo cannot be called on $callback (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1425
                            $closure($event);
1426
1427
                            return true;
1428
                        }
1429
1430
                        return false;
1431
                    }),
1432
                    $this->greaterThan(0)
1433
                );
1434
1435
        $formContractor = $this->createMock(FormContractorInterface::class);
1436
        $formContractor
1437
                ->method('getDefaultOptions')
1438
                ->willReturn([]);
1439
        $formContractor
1440
                ->method('getFormBuilder')
1441
                ->willReturn($formBuild);
1442
1443
        $modelAdmin->setFormContractor($formContractor);
1444
        $modelAdmin->setSubject($object);
1445
        $modelAdmin->defineFormBuilder($formBuild);
1446
        $modelAdmin->getForm();
1447
    }
1448
1449
    public function testCanAddInlineValidationOnlyForGenericMetadata(): void
1450
    {
1451
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1452
        $object = new \stdClass();
1453
1454
        $labelTranslatorStrategy = $this->createStub(LabelTranslatorStrategyInterface::class);
1455
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1456
1457
        $validator = $this->createStub(ValidatorInterface::class);
1458
        $metadata = $this->createStub(PropertyMetadataInterface::class);
1459
        $validator
1460
            ->method('getMetadataFor')
1461
            ->willReturn($metadata);
1462
        $modelAdmin->setValidator($validator);
1463
1464
        $modelManager = $this->createStub(ModelManagerInterface::class);
1465
        $modelManager
1466
            ->method('getNewFieldDescriptionInstance')
1467
            ->willReturn(new FieldDescription());
1468
        $modelAdmin->setModelManager($modelManager);
1469
1470
        $event = $this->createStub(FormEvent::class);
1471
        $event
1472
            ->method('getData')
1473
            ->willReturn($object);
1474
1475
        $formBuild = $this->createStub(FormBuilder::class);
1476
1477
        $formContractor = $this->createStub(FormContractorInterface::class);
1478
        $formContractor
1479
            ->method('getDefaultOptions')
1480
            ->willReturn([]);
1481
        $formContractor
1482
            ->method('getFormBuilder')
1483
            ->willReturn($formBuild);
1484
1485
        $modelAdmin->setFormContractor($formContractor);
1486
        $modelAdmin->setSubject($object);
1487
1488
        $this->expectException(\RuntimeException::class);
1489
        $this->expectExceptionMessage(
1490
            sprintf(
1491
                'Cannot add inline validator for stdClass because its metadata is an instance of %s instead of Symfony\Component\Validator\Mapping\GenericMetadata',
1492
                \get_class($metadata)
1493
            )
1494
        );
1495
1496
        $modelAdmin->defineFormBuilder($formBuild);
1497
    }
1498
1499
    public function testRemoveFieldFromFormGroup(): void
1500
    {
1501
        $formGroups = [
1502
            'foobar' => [
1503
                'fields' => [
1504
                    'foo' => 'foo',
1505
                    'bar' => 'bar',
1506
                ],
1507
            ],
1508
        ];
1509
1510
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1511
        $admin->setFormGroups($formGroups);
1512
1513
        $admin->removeFieldFromFormGroup('foo');
1514
        $this->assertSame($admin->getFormGroups(), [
1515
            'foobar' => [
1516
                'fields' => [
1517
                    'bar' => 'bar',
1518
                ],
1519
            ],
1520
        ]);
1521
1522
        $admin->removeFieldFromFormGroup('bar');
1523
        $this->assertSame($admin->getFormGroups(), []);
1524
    }
1525
1526
    public function testGetFilterParameters(): void
1527
    {
1528
        $authorId = uniqid();
1529
1530
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1531
1532
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1533
        $postAdmin->addChild($commentAdmin, 'post__author');
1534
1535
        $request = $this->createMock(Request::class);
1536
        $query = $this->createMock(ParameterBag::class);
1537
        $query
1538
            ->method('get')
1539
            ->willReturn([
1540
                'filter' => [
1541
                    '_page' => '1',
1542
                    '_per_page' => '32',
1543
                ],
1544
            ]);
1545
1546
        $request->query = $query;
1547
        $request
1548
            ->method('get')
1549
            ->willReturn($authorId);
1550
1551
        $commentAdmin->setRequest($request);
1552
1553
        $modelManager = $this->createMock(ModelManagerInterface::class);
1554
        $modelManager
1555
            ->method('getDefaultSortValues')
1556
            ->willReturn([]);
1557
1558
        $commentAdmin->setModelManager($modelManager);
1559
1560
        $parameters = $commentAdmin->getFilterParameters();
1561
1562
        $this->assertTrue(isset($parameters['post__author']));
1563
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1564
    }
1565
1566
    public function testGetFilterFieldDescription(): void
1567
    {
1568
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1569
1570
        $fooFieldDescription = new FieldDescription();
1571
        $barFieldDescription = new FieldDescription();
1572
        $bazFieldDescription = new FieldDescription();
1573
1574
        $modelManager = $this->createMock(ModelManagerInterface::class);
1575
        $modelManager->expects($this->exactly(3))
1576
            ->method('getNewFieldDescriptionInstance')
1577
            ->willReturnCallback(static function ($adminClass, string $name, $filterOptions) use ($fooFieldDescription, $barFieldDescription, $bazFieldDescription) {
0 ignored issues
show
Unused Code introduced by
The parameter $filterOptions is not used and could be removed.

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

Loading history...
1578
                switch ($name) {
1579
                    case 'foo':
1580
                        $fieldDescription = $fooFieldDescription;
1581
1582
                        break;
1583
1584
                    case 'bar':
1585
                        $fieldDescription = $barFieldDescription;
1586
1587
                        break;
1588
1589
                    case 'baz':
1590
                        $fieldDescription = $bazFieldDescription;
1591
1592
                        break;
1593
1594
                    default:
1595
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1596
                        break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1597
                }
1598
1599
                $fieldDescription->setName($name);
1600
1601
                return $fieldDescription;
1602
            });
1603
1604
        $modelAdmin->setModelManager($modelManager);
1605
1606
        $pager = $this->createMock(PagerInterface::class);
1607
1608
        $datagrid = $this->createMock(DatagridInterface::class);
1609
        $datagrid->expects($this->once())
1610
            ->method('getPager')
1611
            ->willReturn($pager);
1612
1613
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1614
        $datagridBuilder->expects($this->once())
1615
            ->method('getBaseDatagrid')
1616
            ->with($this->identicalTo($modelAdmin), [])
1617
            ->willReturn($datagrid);
1618
1619
        $datagridBuilder->expects($this->exactly(3))
1620
            ->method('addFilter')
1621
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1622
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1623
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1624
            });
1625
1626
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1627
1628
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1629
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1630
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1631
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1632
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1633
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1634
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1635
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1636
    }
1637
1638
    public function testGetSubjectNoRequest(): void
1639
    {
1640
        $modelManager = $this->createMock(ModelManagerInterface::class);
1641
        $modelManager
1642
            ->expects($this->never())
1643
            ->method('find');
1644
1645
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1646
        $admin->setModelManager($modelManager);
1647
1648
        $this->assertFalse($admin->hasSubject());
1649
    }
1650
1651
    public function testGetSideMenu(): void
1652
    {
1653
        $item = $this->createMock(ItemInterface::class);
1654
        $item
1655
            ->expects($this->once())
1656
            ->method('setChildrenAttribute')
1657
            ->with('class', 'nav navbar-nav');
1658
        $item
1659
            ->expects($this->once())
1660
            ->method('setExtra')
1661
            ->with('translation_domain', 'foo_bar_baz');
1662
1663
        $menuFactory = $this->createMock(FactoryInterface::class);
1664
        $menuFactory
1665
            ->expects($this->once())
1666
            ->method('createItem')
1667
            ->willReturn($item);
1668
1669
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1670
        $modelAdmin->setMenuFactory($menuFactory);
1671
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1672
1673
        $modelAdmin->getSideMenu('foo');
1674
    }
1675
1676
    /**
1677
     * @return array
1678
     */
1679
    public function provideGetSubject()
1680
    {
1681
        return [
1682
            [23],
1683
            ['azerty'],
1684
            ['4f69bbb5f14a13347f000092'],
1685
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1686
            [sprintf('123%smy_type', AdapterInterface::ID_SEPARATOR)], // composite keys are supported
1687
        ];
1688
    }
1689
1690
    /**
1691
     * @dataProvider provideGetSubject
1692
     */
1693
    public function testGetSubjectFailed($id): void
1694
    {
1695
        $modelManager = $this->createMock(ModelManagerInterface::class);
1696
        $modelManager
1697
            ->expects($this->once())
1698
            ->method('find')
1699
            ->with('NewsBundle\Entity\Post', $id)
1700
            ->willReturn(null); // entity not found
1701
1702
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1703
        $admin->setModelManager($modelManager);
1704
1705
        $admin->setRequest(new Request(['id' => $id]));
1706
        $this->assertFalse($admin->hasSubject());
1707
    }
1708
1709
    /**
1710
     * @dataProvider provideGetSubject
1711
     */
1712
    public function testGetSubject($id): void
1713
    {
1714
        $model = new Post();
1715
1716
        $modelManager = $this->createMock(ModelManagerInterface::class);
1717
        $modelManager
1718
            ->expects($this->once())
1719
            ->method('find')
1720
            ->with('NewsBundle\Entity\Post', $id)
1721
            ->willReturn($model);
1722
1723
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1724
        $admin->setModelManager($modelManager);
1725
1726
        $admin->setRequest(new Request(['id' => $id]));
1727
        $this->assertTrue($admin->hasSubject());
1728
        $this->assertSame($model, $admin->getSubject());
1729
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
1730
    }
1731
1732
    public function testGetSubjectWithParentDescription(): void
1733
    {
1734
        $adminId = 1;
1735
1736
        $comment = new Comment();
1737
1738
        $modelManager = $this->createMock(ModelManagerInterface::class);
1739
        $modelManager
1740
            ->method('find')
1741
            ->with('NewsBundle\Entity\Comment', $adminId)
1742
            ->willReturn($comment);
1743
1744
        $request = new Request(['id' => $adminId]);
1745
1746
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1747
        $postAdmin->setRequest($request);
1748
1749
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1750
        $commentAdmin->setRequest($request);
1751
        $commentAdmin->setModelManager($modelManager);
1752
1753
        $this->assertTrue($commentAdmin->hasSubject());
1754
        $this->assertSame($comment, $commentAdmin->getSubject());
1755
1756
        $commentAdmin->setSubject(null);
1757
        $commentAdmin->setParentFieldDescription(new FieldDescription());
1758
1759
        $this->assertFalse($commentAdmin->hasSubject());
1760
    }
1761
1762
    /**
1763
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1764
     */
1765
    public function testGetActionButtonsList(): void
1766
    {
1767
        $expected = [
1768
            'create' => [
1769
                'template' => 'Foo.html.twig',
1770
            ],
1771
        ];
1772
1773
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1774
1775
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1776
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
1777
1778
        $admin->setTemplateRegistry($templateRegistry->reveal());
1779
1780
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1781
        $securityHandler
1782
            ->expects($this->once())
1783
            ->method('isGranted')
1784
            ->with($admin, 'CREATE', $admin)
1785
            ->willReturn(true);
1786
        $admin->setSecurityHandler($securityHandler);
1787
1788
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1789
        $routeGenerator
1790
            ->expects($this->once())
1791
            ->method('hasAdminRoute')
1792
            ->with($admin, 'create')
1793
            ->willReturn(true);
1794
        $admin->setRouteGenerator($routeGenerator);
1795
1796
        $this->assertSame($expected, $admin->getActionButtons('list', null));
1797
    }
1798
1799
    /**
1800
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1801
     */
1802
    public function testGetActionButtonsListCreateDisabled(): void
1803
    {
1804
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1805
1806
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1807
        $securityHandler
1808
            ->expects($this->once())
1809
            ->method('isGranted')
1810
            ->with($admin, 'CREATE', $admin)
1811
            ->willReturn(false);
1812
        $admin->setSecurityHandler($securityHandler);
1813
1814
        $this->assertSame([], $admin->getActionButtons('list', null));
1815
    }
1816
1817
    /**
1818
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
1819
     */
1820
    public function testGetBatchActions(): void
1821
    {
1822
        $expected = [
1823
            'delete' => [
1824
                'label' => 'action_delete',
1825
                'translation_domain' => 'SonataAdminBundle',
1826
                'ask_confirmation' => true, // by default always true
1827
            ],
1828
            'foo' => [
1829
                'label' => 'action_foo',
1830
                'translation_domain' => 'SonataAdminBundle',
1831
            ],
1832
            'bar' => [
1833
                'label' => 'batch.label_bar',
1834
                'translation_domain' => 'SonataAdminBundle',
1835
            ],
1836
            'baz' => [
1837
                'label' => 'action_baz',
1838
                'translation_domain' => 'AcmeAdminBundle',
1839
            ],
1840
        ];
1841
1842
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
1843
1844
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1845
        $labelTranslatorStrategy
1846
            ->method('getLabel')
1847
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
1848
                return sprintf('%s.%s_%s', $context, $type, $label);
1849
            });
1850
1851
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1852
        $admin->setRouteBuilder($pathInfo);
1853
        $admin->setTranslationDomain('SonataAdminBundle');
1854
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1855
1856
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1857
        $routeGenerator
1858
            ->expects($this->once())
1859
            ->method('hasAdminRoute')
1860
            ->with($admin, 'delete')
1861
            ->willReturn(true);
1862
        $admin->setRouteGenerator($routeGenerator);
1863
1864
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1865
        $securityHandler
1866
            ->method('isGranted')
1867
            ->willReturnCallback(static function (AdminInterface $adminIn, string $attributes, $object = null) use ($admin): bool {
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

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

Loading history...
1868
                return $admin === $adminIn && 'DELETE' === $attributes;
1869
            });
1870
        $admin->setSecurityHandler($securityHandler);
1871
1872
        $this->assertSame($expected, $admin->getBatchActions());
1873
    }
1874
1875
    /**
1876
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
1877
     */
1878
    public function testShowMosaicButton(): void
1879
    {
1880
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1881
        $listModes = $admin->getListModes();
1882
1883
        $admin->showMosaicButton(true);
1884
1885
        $this->assertSame($listModes, $admin->getListModes());
1886
    }
1887
1888
    /**
1889
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
1890
     */
1891
    public function testShowMosaicButtonHideMosaic(): void
1892
    {
1893
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1894
        $listModes = $admin->getListModes();
1895
        $expected['list'] = $listModes['list'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$expected was never initialized. Although not strictly required by PHP, it is generally a good practice to add $expected = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1896
1897
        $admin->showMosaicButton(false);
1898
1899
        $this->assertSame($expected, $admin->getListModes());
1900
    }
1901
1902
    /**
1903
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
1904
     * @dataProvider provideGetBaseRouteName
1905
     */
1906
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
1907
    {
1908
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
1909
        $routerMock = $this->createMock(RouterInterface::class);
1910
1911
        $routerMock->method('generate')->willReturn('/admin/post');
1912
1913
        $routeGenerator = new DefaultRouteGenerator(
1914
            $routerMock,
1915
            new RoutesCache($this->cacheTempFolder, true)
1916
        );
1917
1918
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
1919
        $admin->setRouteBuilder($pathInfo);
1920
        $admin->setRouteGenerator($routeGenerator);
1921
        $admin->initialize();
1922
1923
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1924
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
1925
1926
        $admin->setTemplateRegistry($templateRegistry->reveal());
1927
1928
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1929
        $securityHandler
1930
            ->method('isGranted')
1931
            ->willReturnCallback(static function (AdminInterface $adminIn, string $attributes, $object = null) use ($admin): bool {
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

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

Loading history...
1932
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
1933
            });
1934
1935
        $admin->setSecurityHandler($securityHandler);
1936
1937
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
1938
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
1939
    }
1940
1941
    public function testDefaultFilters(): void
1942
    {
1943
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1944
1945
        $subjectId = uniqid();
1946
1947
        $request = $this->createMock(Request::class);
1948
        $query = $this->createMock(ParameterBag::class);
1949
        $query
1950
            ->method('get')
1951
            ->with($this->equalTo('filter'))
1952
            ->willReturn([
1953
                'a' => [
1954
                    'value' => 'b',
1955
                ],
1956
                'foo' => [
1957
                    'type' => '1',
1958
                    'value' => 'bar',
1959
                ],
1960
                'baz' => [
1961
                    'type' => '5',
1962
                    'value' => 'test',
1963
                ],
1964
            ]);
1965
        $request->query = $query;
1966
1967
        $request
1968
            ->method('get')
1969
            ->willReturn($subjectId);
1970
1971
        $admin->setRequest($request);
1972
1973
        $modelManager = $this->createMock(ModelManagerInterface::class);
1974
        $modelManager
1975
            ->method('getDefaultSortValues')
1976
            ->willReturn([]);
1977
1978
        $admin->setModelManager($modelManager);
1979
1980
        $this->assertSame([
1981
            'foo' => [
1982
                'type' => '1',
1983
                'value' => 'bar',
1984
            ],
1985
            'baz' => [
1986
                'type' => '5',
1987
                'value' => 'test',
1988
            ],
1989
            'a' => [
1990
                'value' => 'b',
1991
            ],
1992
            '_per_page' => 25,
1993
        ], $admin->getFilterParameters());
1994
1995
        $this->assertTrue($admin->isDefaultFilter('foo'));
1996
        $this->assertFalse($admin->isDefaultFilter('bar'));
1997
        $this->assertFalse($admin->isDefaultFilter('a'));
1998
    }
1999
2000
    public function testGetDataSourceIterator(): void
2001
    {
2002
        $datagrid = $this->createMock(DatagridInterface::class);
2003
        $datagrid->method('buildPager');
2004
2005
        $modelManager = $this->createMock(ModelManagerInterface::class);
2006
        $modelManager->method('getExportFields')->willReturn([
2007
            'field',
2008
            'foo',
2009
            'bar',
2010
        ]);
2011
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2012
            ->with($this->equalTo($datagrid), $this->equalTo([
2013
                'Feld' => 'field',
2014
                1 => 'foo',
2015
                2 => 'bar',
2016
            ]))
2017
            ->willReturn(new ArraySourceIterator([]));
2018
2019
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2020
            ->disableOriginalConstructor()
2021
            ->setMethods(['getClass', 'getDatagrid', 'getTranslationLabel', 'trans'])
2022
            ->getMockForAbstractClass();
2023
        $admin->method('getClass')->willReturn('App\Admin\MyAdmin');
2024
        $admin->method('getDatagrid')->willReturn($datagrid);
2025
        $admin->setModelManager($modelManager);
2026
2027
        $admin
2028
            ->method('getTranslationLabel')
2029
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2030
                return sprintf('%s.%s_%s', $context, $type, $label);
2031
            });
2032
        $admin
2033
            ->method('trans')
2034
            ->willReturnCallback(static function (string $label): string {
2035
                if ('export.label_field' === $label) {
2036
                    return 'Feld';
2037
                }
2038
2039
                return $label;
2040
            });
2041
2042
        $admin->getDataSourceIterator();
2043
    }
2044
2045
    public function testCircularChildAdmin(): void
2046
    {
2047
        $this->expectException(\RuntimeException::class);
2048
        $this->expectExceptionMessage(
2049
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2050
        );
2051
2052
        $postAdmin = new PostAdmin(
2053
            'sonata.post.admin.post',
2054
            'Application\Sonata\NewsBundle\Entity\Post',
2055
            'Sonata\NewsBundle\Controller\PostAdminController'
2056
        );
2057
        $commentAdmin = new CommentAdmin(
2058
            'sonata.post.admin.comment',
2059
            'Application\Sonata\NewsBundle\Entity\Comment',
2060
            'Sonata\NewsBundle\Controller\CommentAdminController'
2061
        );
2062
        $postAdmin->addChild($commentAdmin, 'post');
2063
        $commentAdmin->addChild($postAdmin, 'comment');
2064
    }
2065
2066
    public function testCircularChildAdminTripleLevel(): void
2067
    {
2068
        $this->expectException(\RuntimeException::class);
2069
        $this->expectExceptionMessage(
2070
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2071
        );
2072
2073
        $postAdmin = new PostAdmin(
2074
            'sonata.post.admin.post',
2075
            'Application\Sonata\NewsBundle\Entity\Post',
2076
            'Sonata\NewsBundle\Controller\PostAdminController'
2077
        );
2078
        $commentAdmin = new CommentAdmin(
2079
            'sonata.post.admin.comment',
2080
            'Application\Sonata\NewsBundle\Entity\Comment',
2081
            'Sonata\NewsBundle\Controller\CommentAdminController'
2082
        );
2083
        $commentVoteAdmin = new CommentVoteAdmin(
2084
            'sonata.post.admin.comment_vote',
2085
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2086
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2087
        );
2088
        $postAdmin->addChild($commentAdmin, 'post');
2089
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2090
        $commentVoteAdmin->addChild($postAdmin, 'post');
2091
    }
2092
2093
    public function testCircularChildAdminWithItself(): void
2094
    {
2095
        $this->expectException(\RuntimeException::class);
2096
        $this->expectExceptionMessage(
2097
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2098
        );
2099
2100
        $postAdmin = new PostAdmin(
2101
            'sonata.post.admin.post',
2102
            'Application\Sonata\NewsBundle\Entity\Post',
2103
            'Sonata\NewsBundle\Controller\PostAdminController'
2104
        );
2105
        $postAdmin->addChild($postAdmin, 'post');
2106
    }
2107
2108
    public function testGetRootAncestor(): void
2109
    {
2110
        $postAdmin = new PostAdmin(
2111
            'sonata.post.admin.post',
2112
            'Application\Sonata\NewsBundle\Entity\Post',
2113
            'Sonata\NewsBundle\Controller\PostAdminController'
2114
        );
2115
        $commentAdmin = new CommentAdmin(
2116
            'sonata.post.admin.comment',
2117
            'Application\Sonata\NewsBundle\Entity\Comment',
2118
            'Sonata\NewsBundle\Controller\CommentAdminController'
2119
        );
2120
        $commentVoteAdmin = new CommentVoteAdmin(
2121
            'sonata.post.admin.comment_vote',
2122
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2123
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2124
        );
2125
2126
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2127
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2128
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2129
2130
        $postAdmin->addChild($commentAdmin, 'post');
2131
2132
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2133
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2134
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2135
2136
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2137
2138
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2139
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2140
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2141
    }
2142
2143
    public function testGetChildDepth(): void
2144
    {
2145
        $postAdmin = new PostAdmin(
2146
            'sonata.post.admin.post',
2147
            'Application\Sonata\NewsBundle\Entity\Post',
2148
            'Sonata\NewsBundle\Controller\PostAdminController'
2149
        );
2150
        $commentAdmin = new CommentAdmin(
2151
            'sonata.post.admin.comment',
2152
            'Application\Sonata\NewsBundle\Entity\Comment',
2153
            'Sonata\NewsBundle\Controller\CommentAdminController'
2154
        );
2155
        $commentVoteAdmin = new CommentVoteAdmin(
2156
            'sonata.post.admin.comment_vote',
2157
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2158
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2159
        );
2160
2161
        $this->assertSame(0, $postAdmin->getChildDepth());
2162
        $this->assertSame(0, $commentAdmin->getChildDepth());
2163
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2164
2165
        $postAdmin->addChild($commentAdmin, 'post');
2166
2167
        $this->assertSame(0, $postAdmin->getChildDepth());
2168
        $this->assertSame(1, $commentAdmin->getChildDepth());
2169
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2170
2171
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2172
2173
        $this->assertSame(0, $postAdmin->getChildDepth());
2174
        $this->assertSame(1, $commentAdmin->getChildDepth());
2175
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2176
    }
2177
2178
    public function testGetCurrentLeafChildAdmin(): void
2179
    {
2180
        $postAdmin = new PostAdmin(
2181
            'sonata.post.admin.post',
2182
            'Application\Sonata\NewsBundle\Entity\Post',
2183
            'Sonata\NewsBundle\Controller\PostAdminController'
2184
        );
2185
        $commentAdmin = new CommentAdmin(
2186
            'sonata.post.admin.comment',
2187
            'Application\Sonata\NewsBundle\Entity\Comment',
2188
            'Sonata\NewsBundle\Controller\CommentAdminController'
2189
        );
2190
        $commentVoteAdmin = new CommentVoteAdmin(
2191
            'sonata.post.admin.comment_vote',
2192
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2193
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2194
        );
2195
2196
        $postAdmin->addChild($commentAdmin, 'post');
2197
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2198
2199
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2200
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2201
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2202
2203
        $commentAdmin->setCurrentChild(true);
2204
2205
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2206
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2207
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2208
2209
        $commentVoteAdmin->setCurrentChild(true);
2210
2211
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2212
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2213
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2214
    }
2215
2216
    public function testAdminAvoidInifiniteLoop(): void
2217
    {
2218
        $this->expectNotToPerformAssertions();
2219
2220
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2221
2222
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2223
        $admin->setSubject(new \stdClass());
2224
2225
        $admin->setFormContractor(new FormContractor($formFactory));
2226
2227
        $admin->setShowBuilder(new ShowBuilder());
2228
2229
        $admin->setListBuilder(new ListBuilder());
2230
2231
        $pager = $this->createStub(PagerInterface::class);
2232
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2233
2234
        $validator = $this->createMock(ValidatorInterface::class);
2235
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2236
        $admin->setValidator($validator);
2237
2238
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2239
        $routeGenerator->method('hasAdminRoute')->willReturn(false);
2240
        $admin->setRouteGenerator($routeGenerator);
2241
2242
        $admin->getForm();
2243
        $admin->getShow();
2244
        $admin->getList();
2245
        $admin->getDatagrid();
2246
    }
2247
}
2248