Completed
Push — master ( 57b7f2...4f95ff )
by Grégoire
28:13 queued 01:46
created

AdminTest::testDefaultFilters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 54
rs 9.0036
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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

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

Loading history...
2057
        $admin->setDatagridBuilder($datagridBuilder);
2058
        $admin->setModelManager($modelManager);
2059
        $admin->setLabelTranslatorStrategy(new UnderscoreLabelTranslatorStrategy());
2060
2061
        $admin->getDataSourceIterator();
2062
    }
2063
2064
    public function testCircularChildAdmin(): void
2065
    {
2066
        $this->expectException(\RuntimeException::class);
2067
        $this->expectExceptionMessage(
2068
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2069
        );
2070
2071
        $postAdmin = new PostAdmin(
2072
            'sonata.post.admin.post',
2073
            'Application\Sonata\NewsBundle\Entity\Post',
2074
            'Sonata\NewsBundle\Controller\PostAdminController'
2075
        );
2076
        $commentAdmin = new CommentAdmin(
2077
            'sonata.post.admin.comment',
2078
            'Application\Sonata\NewsBundle\Entity\Comment',
2079
            'Sonata\NewsBundle\Controller\CommentAdminController'
2080
        );
2081
        $postAdmin->addChild($commentAdmin, 'post');
2082
        $commentAdmin->addChild($postAdmin, 'comment');
2083
    }
2084
2085
    public function testCircularChildAdminTripleLevel(): void
2086
    {
2087
        $this->expectException(\RuntimeException::class);
2088
        $this->expectExceptionMessage(
2089
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2090
        );
2091
2092
        $postAdmin = new PostAdmin(
2093
            'sonata.post.admin.post',
2094
            'Application\Sonata\NewsBundle\Entity\Post',
2095
            'Sonata\NewsBundle\Controller\PostAdminController'
2096
        );
2097
        $commentAdmin = new CommentAdmin(
2098
            'sonata.post.admin.comment',
2099
            'Application\Sonata\NewsBundle\Entity\Comment',
2100
            'Sonata\NewsBundle\Controller\CommentAdminController'
2101
        );
2102
        $commentVoteAdmin = new CommentVoteAdmin(
2103
            'sonata.post.admin.comment_vote',
2104
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2105
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2106
        );
2107
        $postAdmin->addChild($commentAdmin, 'post');
2108
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2109
        $commentVoteAdmin->addChild($postAdmin, 'post');
2110
    }
2111
2112
    public function testCircularChildAdminWithItself(): void
2113
    {
2114
        $this->expectException(\RuntimeException::class);
2115
        $this->expectExceptionMessage(
2116
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2117
        );
2118
2119
        $postAdmin = new PostAdmin(
2120
            'sonata.post.admin.post',
2121
            'Application\Sonata\NewsBundle\Entity\Post',
2122
            'Sonata\NewsBundle\Controller\PostAdminController'
2123
        );
2124
        $postAdmin->addChild($postAdmin, 'post');
2125
    }
2126
2127
    public function testGetRootAncestor(): void
2128
    {
2129
        $postAdmin = new PostAdmin(
2130
            'sonata.post.admin.post',
2131
            'Application\Sonata\NewsBundle\Entity\Post',
2132
            'Sonata\NewsBundle\Controller\PostAdminController'
2133
        );
2134
        $commentAdmin = new CommentAdmin(
2135
            'sonata.post.admin.comment',
2136
            'Application\Sonata\NewsBundle\Entity\Comment',
2137
            'Sonata\NewsBundle\Controller\CommentAdminController'
2138
        );
2139
        $commentVoteAdmin = new CommentVoteAdmin(
2140
            'sonata.post.admin.comment_vote',
2141
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2142
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2143
        );
2144
2145
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2146
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2147
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2148
2149
        $postAdmin->addChild($commentAdmin, 'post');
2150
2151
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2152
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2153
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2154
2155
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2156
2157
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2158
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2159
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2160
    }
2161
2162
    public function testGetChildDepth(): void
2163
    {
2164
        $postAdmin = new PostAdmin(
2165
            'sonata.post.admin.post',
2166
            'Application\Sonata\NewsBundle\Entity\Post',
2167
            'Sonata\NewsBundle\Controller\PostAdminController'
2168
        );
2169
        $commentAdmin = new CommentAdmin(
2170
            'sonata.post.admin.comment',
2171
            'Application\Sonata\NewsBundle\Entity\Comment',
2172
            'Sonata\NewsBundle\Controller\CommentAdminController'
2173
        );
2174
        $commentVoteAdmin = new CommentVoteAdmin(
2175
            'sonata.post.admin.comment_vote',
2176
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2177
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2178
        );
2179
2180
        $this->assertSame(0, $postAdmin->getChildDepth());
2181
        $this->assertSame(0, $commentAdmin->getChildDepth());
2182
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2183
2184
        $postAdmin->addChild($commentAdmin, 'post');
2185
2186
        $this->assertSame(0, $postAdmin->getChildDepth());
2187
        $this->assertSame(1, $commentAdmin->getChildDepth());
2188
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2189
2190
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2191
2192
        $this->assertSame(0, $postAdmin->getChildDepth());
2193
        $this->assertSame(1, $commentAdmin->getChildDepth());
2194
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2195
    }
2196
2197
    public function testGetCurrentLeafChildAdmin(): void
2198
    {
2199
        $postAdmin = new PostAdmin(
2200
            'sonata.post.admin.post',
2201
            'Application\Sonata\NewsBundle\Entity\Post',
2202
            'Sonata\NewsBundle\Controller\PostAdminController'
2203
        );
2204
        $commentAdmin = new CommentAdmin(
2205
            'sonata.post.admin.comment',
2206
            'Application\Sonata\NewsBundle\Entity\Comment',
2207
            'Sonata\NewsBundle\Controller\CommentAdminController'
2208
        );
2209
        $commentVoteAdmin = new CommentVoteAdmin(
2210
            'sonata.post.admin.comment_vote',
2211
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2212
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2213
        );
2214
2215
        $postAdmin->addChild($commentAdmin, 'post');
2216
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2217
2218
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2219
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2220
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2221
2222
        $commentAdmin->setCurrentChild(true);
2223
2224
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2225
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2226
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2227
2228
        $commentVoteAdmin->setCurrentChild(true);
2229
2230
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2231
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2232
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2233
    }
2234
2235
    public function testAdminAvoidInifiniteLoop(): void
2236
    {
2237
        $this->expectNotToPerformAssertions();
2238
2239
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2240
2241
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2242
        $admin->setSubject(new \stdClass());
2243
2244
        $admin->setFormContractor(new FormContractor($formFactory));
2245
2246
        $admin->setShowBuilder(new ShowBuilder());
2247
2248
        $admin->setListBuilder(new ListBuilder());
2249
2250
        $pager = $this->createStub(PagerInterface::class);
2251
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2252
2253
        $validator = $this->createMock(ValidatorInterface::class);
2254
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2255
        $admin->setValidator($validator);
2256
2257
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2258
        $routeGenerator->method('hasAdminRoute')->willReturn(false);
2259
        $admin->setRouteGenerator($routeGenerator);
2260
2261
        $admin->getForm();
2262
        $admin->getShow();
2263
        $admin->getList();
2264
        $admin->getDatagrid();
2265
    }
2266
}
2267