Completed
Push — master ( 2cd3d6...ece51a )
by Jordi Sala
02:46
created

AdminTest::testCantAccessObjectIfNullPassed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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