Completed
Push — master ( 2bbaee...d0c868 )
by Vincent
02:42
created

AdminTest::testAdminAvoidInifiniteLoop()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 9.424
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\Datagrid\ProxyQueryInterface;
34
use Sonata\AdminBundle\Filter\Persister\FilterPersisterInterface;
35
use Sonata\AdminBundle\Model\AuditManagerInterface;
36
use Sonata\AdminBundle\Model\ModelManagerInterface;
37
use Sonata\AdminBundle\Route\DefaultRouteGenerator;
38
use Sonata\AdminBundle\Route\PathInfoBuilder;
39
use Sonata\AdminBundle\Route\RouteGeneratorInterface;
40
use Sonata\AdminBundle\Route\RoutesCache;
41
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
42
use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface;
43
use Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface;
44
use Sonata\AdminBundle\Tests\App\Builder\DatagridBuilder;
45
use Sonata\AdminBundle\Tests\App\Builder\FormContractor;
46
use Sonata\AdminBundle\Tests\App\Builder\ListBuilder;
47
use Sonata\AdminBundle\Tests\App\Builder\ShowBuilder;
48
use Sonata\AdminBundle\Tests\Fixtures\Admin\AvoidInfiniteLoopAdmin;
49
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentAdmin;
50
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentVoteAdmin;
51
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentWithCustomRouteAdmin;
52
use Sonata\AdminBundle\Tests\Fixtures\Admin\FieldDescription;
53
use Sonata\AdminBundle\Tests\Fixtures\Admin\FilteredAdmin;
54
use Sonata\AdminBundle\Tests\Fixtures\Admin\ModelAdmin;
55
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin;
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\Tag;
62
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
63
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToStringNull;
64
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
65
use Sonata\Doctrine\Adapter\AdapterInterface;
66
use Sonata\Exporter\Source\ArraySourceIterator;
67
use Symfony\Component\DependencyInjection\Container;
68
use Symfony\Component\Filesystem\Filesystem;
69
use Symfony\Component\Form\FormBuilder;
70
use Symfony\Component\Form\FormBuilderInterface;
71
use Symfony\Component\Form\FormEvent;
72
use Symfony\Component\Form\FormEvents;
73
use Symfony\Component\Form\FormFactory;
74
use Symfony\Component\Form\FormRegistry;
75
use Symfony\Component\Form\ResolvedFormTypeFactory;
76
use Symfony\Component\HttpFoundation\ParameterBag;
77
use Symfony\Component\HttpFoundation\Request;
78
use Symfony\Component\PropertyAccess\PropertyAccess;
79
use Symfony\Component\Routing\RouterInterface;
80
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
81
use Symfony\Component\Translation\TranslatorInterface;
82
use Symfony\Component\Validator\Mapping\MemberMetadata;
83
use Symfony\Component\Validator\Validator\ValidatorInterface;
84
85
class AdminTest extends TestCase
86
{
87
    protected $cacheTempFolder;
88
89
    protected function setUp(): void
90
    {
91
        $this->cacheTempFolder = sys_get_temp_dir().'/sonata_test_route';
92
        $filesystem = new Filesystem();
93
        $filesystem->remove($this->cacheTempFolder);
94
    }
95
96
    /**
97
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::__construct
98
     */
99
    public function testConstructor(): void
100
    {
101
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
102
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
103
104
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
105
        $this->assertInstanceOf(AbstractAdmin::class, $admin);
106
        $this->assertSame($class, $admin->getClass());
107
        $this->assertSame($baseControllerName, $admin->getBaseControllerName());
108
    }
109
110
    public function testGetClass(): void
111
    {
112
        $class = Post::class;
113
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
114
115
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
116
117
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
118
119
        $admin->setSubject(new BlogPost());
120
        $this->assertSame(BlogPost::class, $admin->getClass());
121
122
        $admin->setSubClasses(['foo']);
123
        $this->assertSame(BlogPost::class, $admin->getClass());
124
125
        $admin->setSubject(null);
126
        $admin->setSubClasses([]);
127
        $this->assertSame($class, $admin->getClass());
128
129
        $admin->setSubClasses(['foo' => 'bar']);
130
        $admin->setRequest(new Request(['subclass' => 'foo']));
131
        $this->assertSame('bar', $admin->getClass());
132
    }
133
134
    public function testGetClassException(): void
135
    {
136
        $this->expectException(\RuntimeException::class);
137
        $this->expectExceptionMessage('Feature not implemented: an embedded admin cannot have subclass');
138
139
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
140
        $baseControllerName = 'Sonata\NewsBundle\Controller\PostAdminController';
141
142
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
143
        $admin->setParentFieldDescription(new FieldDescription());
144
        $admin->setSubClasses(['foo' => 'bar']);
145
        $admin->setRequest(new Request(['subclass' => 'foo']));
146
        $admin->getClass();
147
    }
148
149
    public function testCheckAccessThrowsExceptionOnMadeUpAction(): void
150
    {
151
        $admin = new PostAdmin(
152
            'sonata.post.admin.post',
153
            'Application\Sonata\NewsBundle\Entity\Post',
154
            'Sonata\NewsBundle\Controller\PostAdminController'
155
        );
156
        $this->expectException(
157
            \InvalidArgumentException::class
158
        );
159
        $this->expectExceptionMessage(
160
            'Action "made-up" could not be found'
161
        );
162
        $admin->checkAccess('made-up');
163
    }
164
165
    public function testCheckAccessThrowsAccessDeniedException(): void
166
    {
167
        $admin = new PostAdmin(
168
            'sonata.post.admin.post',
169
            'Application\Sonata\NewsBundle\Entity\Post',
170
            'Sonata\NewsBundle\Controller\PostAdminController'
171
        );
172
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
173
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
174
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
175
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
176
        $customExtension->getAccessMapping($admin)->willReturn(
177
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
178
        );
179
        $admin->addExtension($customExtension->reveal());
180
        $admin->setSecurityHandler($securityHandler->reveal());
181
        $this->expectException(
182
            AccessDeniedException::class
183
        );
184
        $this->expectExceptionMessage(
185
            'Access Denied to the action custom_action and role EXTRA_CUSTOM_ROLE'
186
        );
187
        $admin->checkAccess('custom_action');
188
    }
189
190
    public function testHasAccessOnMadeUpAction(): void
191
    {
192
        $admin = new PostAdmin(
193
            'sonata.post.admin.post',
194
            'Application\Sonata\NewsBundle\Entity\Post',
195
            'Sonata\NewsBundle\Controller\PostAdminController'
196
        );
197
198
        $this->assertFalse($admin->hasAccess('made-up'));
199
    }
200
201
    public function testHasAccess(): void
202
    {
203
        $admin = new PostAdmin(
204
            'sonata.post.admin.post',
205
            'Application\Sonata\NewsBundle\Entity\Post',
206
            'Sonata\NewsBundle\Controller\PostAdminController'
207
        );
208
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
209
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
210
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
211
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
212
        $customExtension->getAccessMapping($admin)->willReturn(
213
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
214
        );
215
        $admin->addExtension($customExtension->reveal());
216
        $admin->setSecurityHandler($securityHandler->reveal());
217
218
        $this->assertFalse($admin->hasAccess('custom_action'));
219
    }
220
221
    public function testHasAccessAllowsAccess(): void
222
    {
223
        $admin = new PostAdmin(
224
            'sonata.post.admin.post',
225
            'Application\Sonata\NewsBundle\Entity\Post',
226
            'Sonata\NewsBundle\Controller\PostAdminController'
227
        );
228
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
229
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
230
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(true);
231
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
232
        $customExtension->getAccessMapping($admin)->willReturn(
233
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
234
        );
235
        $admin->addExtension($customExtension->reveal());
236
        $admin->setSecurityHandler($securityHandler->reveal());
237
238
        $this->assertTrue($admin->hasAccess('custom_action'));
239
    }
240
241
    public function testHasAccessAllowsAccessEditAction(): void
242
    {
243
        $admin = new PostAdmin(
244
            'sonata.post.admin.post',
245
            'Application\Sonata\NewsBundle\Entity\Post',
246
            'Sonata\NewsBundle\Controller\PostAdminController'
247
        );
248
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
249
        $securityHandler->isGranted($admin, 'EDIT_ROLE', $admin)->willReturn(true);
250
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
251
        $customExtension->getAccessMapping($admin)->willReturn(
252
            ['edit_action' => ['EDIT_ROLE']]
253
        );
254
        $admin->addExtension($customExtension->reveal());
255
        $admin->setSecurityHandler($securityHandler->reveal());
256
257
        $this->assertTrue($admin->hasAccess('edit_action'));
258
    }
259
260
    /**
261
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChild
262
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::addChild
263
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChild
264
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::isChild
265
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChildren
266
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChildren
267
     */
268
    public function testChildren(): void
269
    {
270
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
271
        $this->assertFalse($postAdmin->hasChildren());
272
        $this->assertFalse($postAdmin->hasChild('comment'));
273
274
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
275
        $postAdmin->addChild($commentAdmin, 'post');
276
277
        $this->assertTrue($postAdmin->hasChildren());
278
        $this->assertTrue($postAdmin->hasChild('sonata.post.admin.comment'));
279
280
        $this->assertSame('sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getCode());
281
        $this->assertSame('sonata.post.admin.post|sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getBaseCodeRoute());
282
        $this->assertSame($postAdmin, $postAdmin->getChild('sonata.post.admin.comment')->getParent());
283
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
284
285
        $this->assertFalse($postAdmin->isChild());
286
        $this->assertTrue($commentAdmin->isChild());
287
288
        $this->assertSame(['sonata.post.admin.comment' => $commentAdmin], $postAdmin->getChildren());
289
    }
290
291
    /**
292
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configure
293
     */
294
    public function testConfigure(): void
295
    {
296
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
297
        $this->assertNotNull($admin->getUniqid());
298
299
        $admin->initialize();
300
        $this->assertNotNull($admin->getUniqid());
301
        $this->assertSame('Post', $admin->getClassnameLabel());
302
303
        $admin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
304
        $admin->setClassnameLabel('postcomment');
305
306
        $admin->initialize();
307
        $this->assertSame('postcomment', $admin->getClassnameLabel());
308
    }
309
310
    public function testConfigureWithValidParentAssociationMapping(): void
311
    {
312
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
313
        $admin->setParentAssociationMapping('Category');
314
315
        $admin->initialize();
316
        $this->assertSame('Category', $admin->getParentAssociationMapping());
317
    }
318
319
    public function provideGetBaseRoutePattern()
320
    {
321
        return [
322
            [
323
                'Application\Sonata\NewsBundle\Entity\Post',
324
                '/sonata/news/post',
325
            ],
326
            [
327
                'Application\Sonata\NewsBundle\Document\Post',
328
                '/sonata/news/post',
329
            ],
330
            [
331
                'MyApplication\MyBundle\Entity\Post',
332
                '/myapplication/my/post',
333
            ],
334
            [
335
                'MyApplication\MyBundle\Entity\Post\Category',
336
                '/myapplication/my/post-category',
337
            ],
338
            [
339
                'MyApplication\MyBundle\Entity\Product\Category',
340
                '/myapplication/my/product-category',
341
            ],
342
            [
343
                'MyApplication\MyBundle\Entity\Other\Product\Category',
344
                '/myapplication/my/other-product-category',
345
            ],
346
            [
347
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
348
                '/cmf/foo/menu',
349
            ],
350
            [
351
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
352
                '/cmf/foo/menu',
353
            ],
354
            [
355
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
356
                '/symfony/barbar/menu',
357
            ],
358
            [
359
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
360
                '/symfony/barbar/menu-item',
361
            ],
362
            [
363
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
364
                '/cmf/foo/menu',
365
            ],
366
            [
367
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
368
                '/cmf/foo/menu',
369
            ],
370
            [
371
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
372
                '/cmf/foo/menu',
373
            ],
374
            [
375
                'AppBundle\Entity\User',
376
                '/app/user',
377
            ],
378
            [
379
                'App\Entity\User',
380
                '/app/user',
381
            ],
382
        ];
383
    }
384
385
    /**
386
     * @dataProvider provideGetBaseRoutePattern
387
     */
388
    public function testGetBaseRoutePattern(string $objFqn, string $expected): void
389
    {
390
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
391
        $this->assertSame($expected, $admin->getBaseRoutePattern());
392
    }
393
394
    /**
395
     * @dataProvider provideGetBaseRoutePattern
396
     */
397
    public function testGetBaseRoutePatternWithChildAdmin(string $objFqn, string $expected): void
398
    {
399
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
400
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
401
        $commentAdmin->setParent($postAdmin);
402
403
        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
404
    }
405
406
    /**
407
     * @dataProvider provideGetBaseRoutePattern
408
     */
409
    public function testGetBaseRoutePatternWithTwoNestedChildAdmin(string $objFqn, string $expected): void
410
    {
411
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
412
        $commentAdmin = new CommentAdmin(
413
            'sonata.post.admin.comment',
414
            'Application\Sonata\NewsBundle\Entity\Comment',
415
            'Sonata\NewsBundle\Controller\CommentAdminController'
416
        );
417
        $commentVoteAdmin = new CommentVoteAdmin(
418
            'sonata.post.admin.comment_vote',
419
            'Application\Sonata\NewsBundle\Entity\CommentVote',
420
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
421
        );
422
        $commentAdmin->setParent($postAdmin);
423
        $commentVoteAdmin->setParent($commentAdmin);
424
425
        $this->assertSame($expected.'/{id}/comment/{childId}/commentvote', $commentVoteAdmin->getBaseRoutePattern());
426
    }
427
428
    public function testGetBaseRoutePatternWithSpecifedPattern(): void
429
    {
430
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostWithCustomRouteAdminController');
431
432
        $this->assertSame('/post-custom', $postAdmin->getBaseRoutePattern());
433
    }
434
435
    public function testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern(): void
436
    {
437
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
438
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
439
        $commentAdmin->setParent($postAdmin);
440
441
        $this->assertSame('/sonata/news/post/{id}/comment-custom', $commentAdmin->getBaseRoutePattern());
442
    }
443
444
    public function testGetBaseRoutePatternWithUnreconizedClassname(): void
445
    {
446
        $this->expectException(\RuntimeException::class);
447
448
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
449
        $admin->getBaseRoutePattern();
450
    }
451
452
    public function provideGetBaseRouteName()
453
    {
454
        return [
455
            [
456
                'Application\Sonata\NewsBundle\Entity\Post',
457
                'admin_sonata_news_post',
458
            ],
459
            [
460
                'Application\Sonata\NewsBundle\Document\Post',
461
                'admin_sonata_news_post',
462
            ],
463
            [
464
                'MyApplication\MyBundle\Entity\Post',
465
                'admin_myapplication_my_post',
466
            ],
467
            [
468
                'MyApplication\MyBundle\Entity\Post\Category',
469
                'admin_myapplication_my_post_category',
470
            ],
471
            [
472
                'MyApplication\MyBundle\Entity\Product\Category',
473
                'admin_myapplication_my_product_category',
474
            ],
475
            [
476
                'MyApplication\MyBundle\Entity\Other\Product\Category',
477
                'admin_myapplication_my_other_product_category',
478
            ],
479
            [
480
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
481
                'admin_cmf_foo_menu',
482
            ],
483
            [
484
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
485
                'admin_cmf_foo_menu',
486
            ],
487
            [
488
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
489
                'admin_symfony_barbar_menu',
490
            ],
491
            [
492
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
493
                'admin_symfony_barbar_menu_item',
494
            ],
495
            [
496
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
497
                'admin_cmf_foo_menu',
498
            ],
499
            [
500
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
501
                'admin_cmf_foo_menu',
502
            ],
503
            [
504
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
505
                'admin_cmf_foo_menu',
506
            ],
507
            [
508
                'AppBundle\Entity\User',
509
                'admin_app_user',
510
            ],
511
            [
512
                'App\Entity\User',
513
                'admin_app_user',
514
            ],
515
        ];
516
    }
517
518
    /**
519
     * @dataProvider provideGetBaseRouteName
520
     */
521
    public function testGetBaseRouteName(string $objFqn, string $expected): void
522
    {
523
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
524
525
        $this->assertSame($expected, $admin->getBaseRouteName());
526
    }
527
528
    /**
529
     * @group legacy
530
     * @expectedDeprecation Calling "addChild" without second argument is deprecated since sonata-project/admin-bundle 3.35 and will not be allowed in 4.0.
531
     * @dataProvider provideGetBaseRouteName
532
     */
533
    public function testGetBaseRouteNameWithChildAdmin(string $objFqn, string $expected): void
534
    {
535
        $routeGenerator = new DefaultRouteGenerator(
536
            $this->createMock(RouterInterface::class),
537
            new RoutesCache($this->cacheTempFolder, true)
538
        );
539
540
        $container = new Container();
541
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
542
543
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
544
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
545
        $container->set('sonata.post.admin.post', $postAdmin);
546
        $postAdmin->setConfigurationPool($pool);
547
        $postAdmin->setRouteBuilder($pathInfo);
548
        $postAdmin->setRouteGenerator($routeGenerator);
549
        $postAdmin->initialize();
550
551
        $commentAdmin = new CommentAdmin(
552
            'sonata.post.admin.comment',
553
            'Application\Sonata\NewsBundle\Entity\Comment',
554
            'Sonata\NewsBundle\Controller\CommentAdminController'
555
        );
556
        $container->set('sonata.post.admin.comment', $commentAdmin);
557
        $commentAdmin->setConfigurationPool($pool);
558
        $commentAdmin->setRouteBuilder($pathInfo);
559
        $commentAdmin->setRouteGenerator($routeGenerator);
560
        $commentAdmin->initialize();
561
562
        $postAdmin->addChild($commentAdmin, 'post');
563
564
        $commentVoteAdmin = new CommentVoteAdmin(
565
            'sonata.post.admin.comment_vote',
566
            'Application\Sonata\NewsBundle\Entity\CommentVote',
567
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
568
        );
569
570
        $container->set('sonata.post.admin.comment_vote', $commentVoteAdmin);
571
        $commentVoteAdmin->setConfigurationPool($pool);
572
        $commentVoteAdmin->setRouteBuilder($pathInfo);
573
        $commentVoteAdmin->setRouteGenerator($routeGenerator);
574
        $commentVoteAdmin->initialize();
575
576
        $commentAdmin->addChild($commentVoteAdmin);
577
        $pool->setAdminServiceIds([
578
            'sonata.post.admin.post',
579
            'sonata.post.admin.comment',
580
            'sonata.post.admin.comment_vote',
581
        ]);
582
583
        $this->assertSame($expected.'_comment', $commentAdmin->getBaseRouteName());
584
585
        $this->assertTrue($postAdmin->hasRoute('show'));
586
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
587
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.show'));
588
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment|sonata.post.admin.comment_vote.show'));
589
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment.list'));
590
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment|sonata.post.admin.comment_vote.list'));
591
        $this->assertFalse($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.edit'));
592
        $this->assertFalse($commentAdmin->hasRoute('edit'));
593
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
594
595
        /*
596
         * Test the route name from request
597
         */
598
        $postListRequest = new Request(
599
            [],
600
            [],
601
            [
602
                '_route' => $postAdmin->getBaseRouteName().'_list',
603
            ]
604
        );
605
606
        $postAdmin->setRequest($postListRequest);
607
        $commentAdmin->setRequest($postListRequest);
608
609
        $this->assertTrue($postAdmin->isCurrentRoute('list'));
610
        $this->assertFalse($postAdmin->isCurrentRoute('create'));
611
        $this->assertFalse($commentAdmin->isCurrentRoute('list'));
612
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('list'));
613
        $this->assertTrue($commentAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
614
        $this->assertFalse($commentAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
615
        $this->assertTrue($commentVoteAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
616
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
617
    }
618
619
    public function testGetBaseRouteNameWithUnreconizedClassname(): void
620
    {
621
        $this->expectException(\RuntimeException::class);
622
623
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
624
        $admin->getBaseRouteName();
625
    }
626
627
    public function testGetBaseRouteNameWithSpecifiedName(): void
628
    {
629
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
630
631
        $this->assertSame('post_custom', $postAdmin->getBaseRouteName());
632
    }
633
634
    public function testGetBaseRouteNameWithChildAdminAndWithSpecifiedName(): void
635
    {
636
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
637
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController');
638
        $commentAdmin->setParent($postAdmin);
639
640
        $this->assertSame('admin_sonata_news_post_comment_custom', $commentAdmin->getBaseRouteName());
641
    }
642
643
    public function testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName(): void
644
    {
645
        $postAdmin = new PostAdmin(
646
            'sonata.post.admin.post',
647
            'Application\Sonata\NewsBundle\Entity\Post',
648
            'Sonata\NewsBundle\Controller\PostAdminController'
649
        );
650
        $commentAdmin = new CommentWithCustomRouteAdmin(
651
            'sonata.post.admin.comment_with_custom_route',
652
            'Application\Sonata\NewsBundle\Entity\Comment',
653
            'Sonata\NewsBundle\Controller\CommentWithCustomRouteAdminController'
654
        );
655
        $commentVoteAdmin = new CommentVoteAdmin(
656
            'sonata.post.admin.comment_vote',
657
            'Application\Sonata\NewsBundle\Entity\CommentVote',
658
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
659
        );
660
        $commentAdmin->setParent($postAdmin);
661
        $commentVoteAdmin->setParent($commentAdmin);
662
663
        $this->assertSame('admin_sonata_news_post_comment_custom_commentvote', $commentVoteAdmin->getBaseRouteName());
664
    }
665
666
    /**
667
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setUniqid
668
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getUniqid
669
     */
670
    public function testSetUniqid(): void
671
    {
672
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
673
674
        $uniqid = uniqid();
675
        $admin->setUniqid($uniqid);
676
677
        $this->assertSame($uniqid, $admin->getUniqid());
678
    }
679
680
    public function testToString(): void
681
    {
682
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
683
684
        $s = new \stdClass();
685
686
        $this->assertNotEmpty($admin->toString($s));
687
688
        $s = new FooToString();
689
        $this->assertSame('salut', $admin->toString($s));
690
691
        // To string method is implemented, but returns null
692
        $s = new FooToStringNull();
693
        $this->assertNotEmpty($admin->toString($s));
694
695
        $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...
696
    }
697
698
    public function testIsAclEnabled(): void
699
    {
700
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
701
702
        $this->assertFalse($postAdmin->isAclEnabled());
703
704
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
705
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
706
        $this->assertTrue($commentAdmin->isAclEnabled());
707
    }
708
709
    /**
710
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
711
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
712
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
713
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
714
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
715
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
716
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
717
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
718
     */
719
    public function testSubClass(): void
720
    {
721
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
722
        $admin = new PostAdmin(
723
            'sonata.post.admin.post',
724
            Post::class,
725
            'Sonata\NewsBundle\Controller\PostAdminController'
726
        );
727
        $this->assertFalse($admin->hasSubClass('test'));
728
        $this->assertFalse($admin->hasActiveSubClass());
729
        $this->assertCount(0, $admin->getSubClasses());
730
        $this->assertSame(Post::class, $admin->getClass());
731
732
        // Just for the record, if there is no inheritance set, the getSubject is not used
733
        // the getSubject can also lead to some issue
734
        $admin->setSubject(new BlogPost());
735
        $this->assertSame(BlogPost::class, $admin->getClass());
736
737
        $admin->setSubClasses([
738
            'extended1' => 'NewsBundle\Entity\PostExtended1',
739
            'extended2' => 'NewsBundle\Entity\PostExtended2',
740
        ]);
741
        $this->assertFalse($admin->hasSubClass('test'));
742
        $this->assertTrue($admin->hasSubClass('extended1'));
743
        $this->assertFalse($admin->hasActiveSubClass());
744
        $this->assertCount(2, $admin->getSubClasses());
745
        $this->assertSame(
746
            BlogPost::class,
747
            $admin->getClass(),
748
            'When there is no subclass in the query the class parameter should be returned'
749
        );
750
751
        $request = new Request(['subclass' => 'extended1']);
752
        $admin->setRequest($request);
753
        $this->assertFalse($admin->hasSubClass('test'));
754
        $this->assertTrue($admin->hasSubClass('extended1'));
755
        $this->assertTrue($admin->hasActiveSubClass());
756
        $this->assertCount(2, $admin->getSubClasses());
757
        $this->assertSame(
758
            'NewsBundle\Entity\PostExtended1',
759
            $admin->getActiveSubClass(),
760
            'It should return the curently active sub class.'
761
        );
762
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
763
        $this->assertSame(
764
            'NewsBundle\Entity\PostExtended1',
765
            $admin->getClass(),
766
            'getClass() should return the name of the sub class when passed through a request query parameter.'
767
        );
768
769
        $request->query->set('subclass', 'inject');
770
771
        $this->expectException(\LogicException::class);
772
        $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
773
774
        $admin->getActiveSubclassCode();
775
    }
776
777
    public function testNonExistantSubclass(): void
778
    {
779
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
780
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
781
782
        $admin->setRequest(new Request(['subclass' => 'inject']));
783
784
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
785
786
        $this->assertTrue($admin->hasActiveSubClass());
787
788
        $this->expectException(\LogicException::class);
789
790
        $admin->getActiveSubClass();
791
    }
792
793
    /**
794
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
795
     */
796
    public function testOnlyOneSubclassNeededToBeActive(): void
797
    {
798
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
799
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
800
        $request = new Request(['subclass' => 'extended1']);
801
        $admin->setRequest($request);
802
        $this->assertTrue($admin->hasActiveSubClass());
803
    }
804
805
    /**
806
     * @group legacy
807
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since sonata-project/admin-bundle 3.30 and will be removed in 4.0.
808
     */
809
    public function testAddSubClassIsDeprecated(): void
810
    {
811
        $admin = new PostAdmin(
812
            'sonata.post.admin.post',
813
            Post::class,
814
            'Sonata\NewsBundle\Controller\PostAdminController'
815
        );
816
        $admin->addSubClass('whatever');
817
    }
818
819
    /**
820
     * @group legacy
821
     */
822
    public function testGetPerPageOptions(): void
823
    {
824
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
825
826
        $perPageOptions = $admin->getPerPageOptions();
827
828
        foreach ($perPageOptions as $perPage) {
829
            $this->assertSame(0, $perPage % 4);
830
        }
831
832
        $admin->setPerPageOptions([500, 1000]);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...in::setPerPageOptions() has been deprecated with message: since sonata-project/admin-bundle 3.67, to be removed in 4.0. Set custom per page options.

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...
833
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
834
    }
835
836
    public function testGetLabelTranslatorStrategy(): void
837
    {
838
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
839
840
        $this->assertNull($admin->getLabelTranslatorStrategy());
841
842
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
843
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
844
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
845
    }
846
847
    public function testGetRouteBuilder(): void
848
    {
849
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
850
851
        $this->assertNull($admin->getRouteBuilder());
852
853
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
854
        $admin->setRouteBuilder($routeBuilder);
855
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
856
    }
857
858
    public function testGetMenuFactory(): void
859
    {
860
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
861
862
        $this->assertNull($admin->getMenuFactory());
863
864
        $menuFactory = $this->createMock(FactoryInterface::class);
865
        $admin->setMenuFactory($menuFactory);
866
        $this->assertSame($menuFactory, $admin->getMenuFactory());
867
    }
868
869
    public function testGetExtensions(): void
870
    {
871
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
872
873
        $this->assertSame([], $admin->getExtensions());
874
875
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
876
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
877
878
        $admin->addExtension($adminExtension1);
879
        $admin->addExtension($adminExtension2);
880
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
881
    }
882
883
    public function testGetFilterTheme(): void
884
    {
885
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
886
887
        $this->assertSame([], $admin->getFilterTheme());
888
889
        $admin->setFilterTheme(['FooTheme']);
890
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
891
    }
892
893
    public function testGetFormTheme(): void
894
    {
895
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
896
897
        $this->assertSame([], $admin->getFormTheme());
898
899
        $admin->setFormTheme(['FooTheme']);
900
901
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
902
    }
903
904
    public function testGetValidator(): void
905
    {
906
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
907
908
        $this->assertNull($admin->getValidator());
909
910
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
911
912
        $admin->setValidator($validator);
913
        $this->assertSame($validator, $admin->getValidator());
914
    }
915
916
    public function testGetSecurityHandler(): void
917
    {
918
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
919
920
        $this->assertNull($admin->getSecurityHandler());
921
922
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
923
        $admin->setSecurityHandler($securityHandler);
924
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
925
    }
926
927
    public function testGetSecurityInformation(): void
928
    {
929
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
930
931
        $this->assertSame([], $admin->getSecurityInformation());
932
933
        $securityInformation = [
934
            'GUEST' => ['VIEW', 'LIST'],
935
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
936
        ];
937
938
        $admin->setSecurityInformation($securityInformation);
939
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
940
    }
941
942
    public function testGetManagerType(): void
943
    {
944
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
945
946
        $this->assertNull($admin->getManagerType());
947
948
        $admin->setManagerType('foo_orm');
949
        $this->assertSame('foo_orm', $admin->getManagerType());
950
    }
951
952
    public function testGetModelManager(): void
953
    {
954
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
955
956
        $this->assertNull($admin->getModelManager());
957
958
        $modelManager = $this->createMock(ModelManagerInterface::class);
959
960
        $admin->setModelManager($modelManager);
961
        $this->assertSame($modelManager, $admin->getModelManager());
962
    }
963
964
    public function testGetBaseCodeRoute(): void
965
    {
966
        $postAdmin = new PostAdmin(
967
            'sonata.post.admin.post',
968
            'NewsBundle\Entity\Post',
969
            'Sonata\NewsBundle\Controller\PostAdminController'
970
        );
971
        $commentAdmin = new CommentAdmin(
972
            'sonata.post.admin.comment',
973
            'Application\Sonata\NewsBundle\Entity\Comment',
974
            'Sonata\NewsBundle\Controller\CommentAdminController'
975
        );
976
977
        $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
978
979
        $postAdmin->addChild($commentAdmin, 'post');
980
981
        $this->assertSame(
982
            'sonata.post.admin.post|sonata.post.admin.comment',
983
            $commentAdmin->getBaseCodeRoute()
984
        );
985
    }
986
987
    public function testGetRouteGenerator(): void
988
    {
989
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
990
991
        $this->assertNull($admin->getRouteGenerator());
992
993
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
994
995
        $admin->setRouteGenerator($routeGenerator);
996
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
997
    }
998
999
    public function testGetConfigurationPool(): void
1000
    {
1001
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1002
1003
        $this->assertNull($admin->getConfigurationPool());
1004
1005
        $pool = $this->getMockBuilder(Pool::class)
1006
            ->disableOriginalConstructor()
1007
            ->getMock();
1008
1009
        $admin->setConfigurationPool($pool);
1010
        $this->assertSame($pool, $admin->getConfigurationPool());
1011
    }
1012
1013
    public function testGetShowBuilder(): void
1014
    {
1015
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1016
1017
        $this->assertNull($admin->getShowBuilder());
1018
1019
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1020
1021
        $admin->setShowBuilder($showBuilder);
1022
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1023
    }
1024
1025
    public function testGetListBuilder(): void
1026
    {
1027
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1028
1029
        $this->assertNull($admin->getListBuilder());
1030
1031
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1032
1033
        $admin->setListBuilder($listBuilder);
1034
        $this->assertSame($listBuilder, $admin->getListBuilder());
1035
    }
1036
1037
    public function testGetDatagridBuilder(): void
1038
    {
1039
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1040
1041
        $this->assertNull($admin->getDatagridBuilder());
1042
1043
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1044
1045
        $admin->setDatagridBuilder($datagridBuilder);
1046
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1047
    }
1048
1049
    public function testGetFormContractor(): void
1050
    {
1051
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1052
1053
        $this->assertNull($admin->getFormContractor());
1054
1055
        $formContractor = $this->createMock(FormContractorInterface::class);
1056
1057
        $admin->setFormContractor($formContractor);
1058
        $this->assertSame($formContractor, $admin->getFormContractor());
1059
    }
1060
1061
    public function testGetRequest(): void
1062
    {
1063
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1064
1065
        $this->assertFalse($admin->hasRequest());
1066
1067
        $request = new Request();
1068
1069
        $admin->setRequest($request);
1070
        $this->assertSame($request, $admin->getRequest());
1071
        $this->assertTrue($admin->hasRequest());
1072
    }
1073
1074
    public function testGetRequestWithException(): void
1075
    {
1076
        $this->expectException(\RuntimeException::class);
1077
        $this->expectExceptionMessage('The Request object has not been set');
1078
1079
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1080
        $admin->getRequest();
1081
    }
1082
1083
    public function testGetTranslationDomain(): void
1084
    {
1085
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1086
1087
        $this->assertSame('messages', $admin->getTranslationDomain());
1088
1089
        $admin->setTranslationDomain('foo');
1090
        $this->assertSame('foo', $admin->getTranslationDomain());
1091
    }
1092
1093
    /**
1094
     * @group legacy
1095
     */
1096
    public function testGetTranslator(): void
1097
    {
1098
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1099
1100
        $this->assertNull($admin->getTranslator());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::getTranslator() 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...
1101
1102
        $translator = $this->createMock(TranslatorInterface::class);
1103
1104
        $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...
1105
        $this->assertSame($translator, $admin->getTranslator());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::getTranslator() 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...
1106
    }
1107
1108
    public function testGetShowGroups(): void
1109
    {
1110
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1111
1112
        $this->assertSame([], $admin->getShowGroups());
1113
1114
        $groups = ['foo', 'bar', 'baz'];
1115
1116
        $admin->setShowGroups($groups);
1117
        $this->assertSame($groups, $admin->getShowGroups());
1118
    }
1119
1120
    public function testGetFormGroups(): void
1121
    {
1122
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1123
1124
        $this->assertSame([], $admin->getFormGroups());
1125
1126
        $groups = ['foo', 'bar', 'baz'];
1127
1128
        $admin->setFormGroups($groups);
1129
        $this->assertSame($groups, $admin->getFormGroups());
1130
    }
1131
1132
    public function testGetMaxPageLinks(): void
1133
    {
1134
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1135
1136
        $this->assertSame(25, $admin->getMaxPageLinks());
1137
1138
        $admin->setMaxPageLinks(14);
1139
        $this->assertSame(14, $admin->getMaxPageLinks());
1140
    }
1141
1142
    /**
1143
     * @group legacy
1144
     */
1145
    public function testGetMaxPerPage(): void
1146
    {
1147
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1148
1149
        $this->assertSame(32, $admin->getMaxPerPage());
1150
1151
        $admin->setMaxPerPage(94);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setMaxPerPage() has been deprecated with message: since sonata-project/admin-bundle 3.67, to be removed in 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...
1152
        $this->assertSame(94, $admin->getMaxPerPage());
1153
    }
1154
1155
    public function testGetLabel(): void
1156
    {
1157
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1158
1159
        $this->assertNull($admin->getLabel());
1160
1161
        $admin->setLabel('FooLabel');
1162
        $this->assertSame('FooLabel', $admin->getLabel());
1163
    }
1164
1165
    public function testGetBaseController(): void
1166
    {
1167
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1168
1169
        $this->assertSame('Sonata\NewsBundle\Controller\PostAdminController', $admin->getBaseControllerName());
1170
1171
        $admin->setBaseControllerName('Sonata\NewsBundle\Controller\FooAdminController');
1172
        $this->assertSame('Sonata\NewsBundle\Controller\FooAdminController', $admin->getBaseControllerName());
1173
    }
1174
1175
    public function testGetIdParameter(): void
1176
    {
1177
        $postAdmin = new PostAdmin(
1178
            'sonata.post.admin.post',
1179
            'NewsBundle\Entity\Post',
1180
            'Sonata\NewsBundle\Controller\PostAdminController'
1181
        );
1182
1183
        $this->assertSame('id', $postAdmin->getIdParameter());
1184
        $this->assertFalse($postAdmin->isChild());
1185
1186
        $commentAdmin = new CommentAdmin(
1187
            'sonata.post.admin.comment',
1188
            'Application\Sonata\NewsBundle\Entity\Comment',
1189
            'Sonata\NewsBundle\Controller\CommentAdminController'
1190
        );
1191
        $commentAdmin->setParent($postAdmin);
1192
1193
        $this->assertTrue($commentAdmin->isChild());
1194
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1195
1196
        $commentVoteAdmin = new CommentVoteAdmin(
1197
            'sonata.post.admin.comment_vote',
1198
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1199
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
1200
        );
1201
        $commentVoteAdmin->setParent($commentAdmin);
1202
1203
        $this->assertTrue($commentVoteAdmin->isChild());
1204
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1205
    }
1206
1207
    public function testGetExportFormats(): void
1208
    {
1209
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1210
1211
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1212
    }
1213
1214
    public function testGetUrlsafeIdentifier(): void
1215
    {
1216
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1217
1218
        $model = new \stdClass();
1219
1220
        $modelManager = $this->createMock(ModelManagerInterface::class);
1221
        $modelManager->expects($this->once())
1222
            ->method('getUrlSafeIdentifier')
1223
            ->with($this->equalTo($model))
1224
            ->willReturn('foo');
1225
        $admin->setModelManager($modelManager);
1226
1227
        $this->assertSame('foo', $admin->getUrlSafeIdentifier($model));
1228
    }
1229
1230
    public function testDeterminedPerPageValue(): void
1231
    {
1232
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1233
1234
        $this->assertFalse($admin->determinedPerPageValue(123));
1235
        $this->assertTrue($admin->determinedPerPageValue(16));
1236
    }
1237
1238
    public function testIsGranted(): void
1239
    {
1240
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1241
        $modelManager = $this->createStub(ModelManagerInterface::class);
1242
        $modelManager
1243
            ->method('getNormalizedIdentifier')
1244
            ->willReturnCallback(static function (?object $model = null): ?string {
1245
                return $model ? $model->id : null;
1246
            });
1247
1248
        $admin->setModelManager($modelManager);
1249
1250
        $entity1 = new \stdClass();
1251
        $entity1->id = '1';
1252
1253
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1254
        $securityHandler
1255
            ->expects($this->exactly(6))
1256
            ->method('isGranted')
1257
            ->willReturnCallback(static function (
1258
                AdminInterface $adminIn,
1259
                string $attributes,
1260
                ?object $object = null
1261
            ) use (
1262
                $admin,
1263
                $entity1
1264
            ): bool {
1265
                return $admin === $adminIn && 'FOO' === $attributes &&
1266
                    ($object === $admin || $object === $entity1);
1267
            });
1268
1269
        $admin->setSecurityHandler($securityHandler);
1270
1271
        $this->assertTrue($admin->isGranted('FOO'));
1272
        $this->assertTrue($admin->isGranted('FOO'));
1273
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1274
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1275
        $this->assertFalse($admin->isGranted('BAR'));
1276
        $this->assertFalse($admin->isGranted('BAR'));
1277
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1278
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1279
1280
        $entity2 = new \stdClass();
1281
        $entity2->id = '2';
1282
1283
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1284
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1285
1286
        $entity3 = new \stdClass();
1287
        $entity3->id = '3';
1288
1289
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1290
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1291
    }
1292
1293
    public function testSupportsPreviewMode(): void
1294
    {
1295
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1296
1297
        $this->assertFalse($admin->supportsPreviewMode());
1298
    }
1299
1300
    public function testGetPermissionsShow(): void
1301
    {
1302
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1303
1304
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1305
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1306
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1307
    }
1308
1309
    public function testShowIn(): void
1310
    {
1311
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1312
1313
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1314
        $securityHandler
1315
            ->method('isGranted')
1316
            ->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...
1317
                return $admin === $adminIn && $attributes === ['LIST'];
1318
            });
1319
1320
        $admin->setSecurityHandler($securityHandler);
1321
1322
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1323
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1324
        $this->assertTrue($admin->showIn('foo'));
1325
    }
1326
1327
    public function testGetObjectIdentifier(): void
1328
    {
1329
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1330
1331
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1332
    }
1333
1334
    /**
1335
     * @group legacy
1336
     */
1337
    public function testTrans(): void
1338
    {
1339
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1340
        $admin->setTranslationDomain('fooMessageDomain');
1341
1342
        $translator = $this->createMock(TranslatorInterface::class);
1343
        $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...
1344
1345
        $translator->expects($this->once())
1346
            ->method('trans')
1347
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1348
            ->willReturn('fooTranslated');
1349
1350
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1351
    }
1352
1353
    /**
1354
     * @group legacy
1355
     */
1356
    public function testTransWithMessageDomain(): void
1357
    {
1358
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1359
1360
        $translator = $this->createMock(TranslatorInterface::class);
1361
        $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...
1362
1363
        $translator->expects($this->once())
1364
            ->method('trans')
1365
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1366
            ->willReturn('fooTranslated');
1367
1368
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1369
    }
1370
1371
    /**
1372
     * @group legacy
1373
     */
1374
    public function testTransChoice(): void
1375
    {
1376
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1377
        $admin->setTranslationDomain('fooMessageDomain');
1378
1379
        $translator = $this->createMock(TranslatorInterface::class);
1380
        $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...
1381
1382
        $translator->expects($this->once())
1383
            ->method('transChoice')
1384
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1385
            ->willReturn('fooTranslated');
1386
1387
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::transChoice() 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...
1388
    }
1389
1390
    /**
1391
     * @group legacy
1392
     */
1393
    public function testTransChoiceWithMessageDomain(): void
1394
    {
1395
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1396
1397
        $translator = $this->createMock(TranslatorInterface::class);
1398
        $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...
1399
1400
        $translator->expects($this->once())
1401
            ->method('transChoice')
1402
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1403
            ->willReturn('fooTranslated');
1404
1405
        $this->assertSame('fooTranslated', $admin->transChoice('foo', 2, ['name' => 'Andrej'], 'fooMessageDomain'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::transChoice() 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...
1406
    }
1407
1408
    public function testSetFilterPersister(): void
1409
    {
1410
        $admin = new class('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController') extends PostAdmin {
1411
            public function persistFilters(): bool
1412
            {
1413
                return $this->persistFilters;
0 ignored issues
show
Deprecated Code introduced by
The property Sonata\AdminBundle\Admin...tAdmin::$persistFilters has been deprecated with message: since sonata-project/admin-bundle 3.34, to be removed in 4.0.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
1414
            }
1415
        };
1416
1417
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1418
1419
        $admin->setFilterPersister($filterPersister);
1420
        $this->assertTrue($admin->persistFilters());
1421
    }
1422
1423
    public function testGetRootCode(): void
1424
    {
1425
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1426
1427
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1428
1429
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1430
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1431
        $parentFieldDescription->expects($this->once())
1432
            ->method('getAdmin')
1433
            ->willReturn($parentAdmin);
1434
1435
        $this->assertFalse($admin->hasParentFieldDescription());
1436
        $admin->setParentFieldDescription($parentFieldDescription);
1437
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1438
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1439
    }
1440
1441
    public function testGetRoot(): void
1442
    {
1443
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1444
1445
        $this->assertSame($admin, $admin->getRoot());
1446
1447
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1448
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1449
        $parentFieldDescription->expects($this->once())
1450
            ->method('getAdmin')
1451
            ->willReturn($parentAdmin);
1452
1453
        $this->assertFalse($admin->hasParentFieldDescription());
1454
        $admin->setParentFieldDescription($parentFieldDescription);
1455
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1456
        $this->assertSame($parentAdmin, $admin->getRoot());
1457
    }
1458
1459
    public function testGetExportFields(): void
1460
    {
1461
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1462
1463
        $modelManager = $this->createMock(ModelManagerInterface::class);
1464
        $modelManager->expects($this->once())
1465
            ->method('getExportFields')
1466
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1467
            ->willReturn(['foo', 'bar']);
1468
1469
        $admin->setModelManager($modelManager);
1470
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1471
    }
1472
1473
    public function testGetPersistentParametersWithNoExtension(): void
1474
    {
1475
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1476
1477
        $this->assertEmpty($admin->getPersistentParameters());
1478
    }
1479
1480
    public function testGetPersistentParametersWithValidExtension(): void
1481
    {
1482
        $expected = [
1483
            'context' => 'foobar',
1484
        ];
1485
1486
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1487
1488
        $extension = $this->createMock(AdminExtensionInterface::class);
1489
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1490
1491
        $admin->addExtension($extension);
1492
1493
        $this->assertSame($expected, $admin->getPersistentParameters());
1494
    }
1495
1496
    public function testGetFormWithNonCollectionParentValue(): void
1497
    {
1498
        $post = new Post();
1499
        $tagAdmin = $this->createTagAdmin($post);
1500
        $tag = $tagAdmin->getSubject();
1501
1502
        $tag->setPosts(null);
1503
        $tagAdmin->getForm();
1504
        $this->assertSame($post, $tag->getPosts());
1505
    }
1506
1507
    public function testGetFormWithCollectionParentValue(): void
1508
    {
1509
        $post = new Post();
1510
        $tagAdmin = $this->createTagAdmin($post);
1511
        $tag = $tagAdmin->getSubject();
1512
1513
        // Case of a doctrine collection
1514
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1515
        $this->assertCount(0, $tag->getPosts());
1516
1517
        $tag->addPost(new Post());
1518
1519
        $this->assertCount(1, $tag->getPosts());
1520
1521
        $tagAdmin->getForm();
1522
1523
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1524
        $this->assertCount(2, $tag->getPosts());
1525
        $this->assertContains($post, $tag->getPosts());
1526
    }
1527
1528
    public function testGetFormWithArrayParentValue(): void
1529
    {
1530
        $post = new Post();
1531
        $tagAdmin = $this->createTagAdmin($post);
1532
        $tag = $tagAdmin->getSubject();
1533
1534
        // Case of an array
1535
        $tag->setPosts([]);
1536
        $this->assertCount(0, $tag->getPosts());
1537
1538
        $tag->addPost(new Post());
1539
1540
        $this->assertCount(1, $tag->getPosts());
1541
1542
        $tagAdmin->getForm();
1543
1544
        $this->assertIsArray($tag->getPosts());
1545
        $this->assertCount(2, $tag->getPosts());
1546
        $this->assertContains($post, $tag->getPosts());
1547
    }
1548
1549
    public function testFormAddPostSubmitEventForPreValidation(): void
1550
    {
1551
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1552
        $object = new \stdClass();
1553
1554
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1555
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1556
1557
        $validator = $this->createMock(ValidatorInterface::class);
1558
        $validator
1559
                ->method('getMetadataFor')
1560
                ->willReturn($this->createMock(MemberMetadata::class));
1561
        $modelAdmin->setValidator($validator);
1562
1563
        $modelManager = $this->createMock(ModelManagerInterface::class);
1564
        $modelManager
1565
            ->method('getNewFieldDescriptionInstance')
1566
            ->willReturn(new FieldDescription());
1567
        $modelAdmin->setModelManager($modelManager);
1568
1569
        // a Admin class to test that preValidate is called
1570
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1571
        $testAdminPreValidate->expects($this->once())
1572
                ->method('preValidate')
1573
                ->with($this->identicalTo($object));
1574
1575
        $event = $this->createMock(FormEvent::class);
1576
        $event
1577
                ->method('getData')
1578
                ->willReturn($object);
1579
1580
        $formBuild = $this->createMock(FormBuilder::class);
1581
        $formBuild->expects($this->once())
1582
                ->method('addEventListener')
1583
                ->with(
1584
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1585
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1586
                        if (\is_callable($callback)) {
1587
                            $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...
1588
                            $closure($event);
1589
1590
                            return true;
1591
                        }
1592
1593
                        return false;
1594
                    }),
1595
                    $this->greaterThan(0)
1596
                );
1597
1598
        $formContractor = $this->createMock(FormContractorInterface::class);
1599
        $formContractor
1600
                ->method('getDefaultOptions')
1601
                ->willReturn([]);
1602
        $formContractor
1603
                ->method('getFormBuilder')
1604
                ->willReturn($formBuild);
1605
1606
        $modelAdmin->setFormContractor($formContractor);
1607
        $modelAdmin->setSubject($object);
1608
        $modelAdmin->defineFormBuilder($formBuild);
1609
        $modelAdmin->getForm();
1610
    }
1611
1612
    public function testRemoveFieldFromFormGroup(): void
1613
    {
1614
        $formGroups = [
1615
            'foobar' => [
1616
                'fields' => [
1617
                    'foo' => 'foo',
1618
                    'bar' => 'bar',
1619
                ],
1620
            ],
1621
        ];
1622
1623
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1624
        $admin->setFormGroups($formGroups);
1625
1626
        $admin->removeFieldFromFormGroup('foo');
1627
        $this->assertSame($admin->getFormGroups(), [
1628
            'foobar' => [
1629
                'fields' => [
1630
                    'bar' => 'bar',
1631
                ],
1632
            ],
1633
        ]);
1634
1635
        $admin->removeFieldFromFormGroup('bar');
1636
        $this->assertSame($admin->getFormGroups(), []);
1637
    }
1638
1639
    public function testGetFilterParameters(): void
1640
    {
1641
        $authorId = uniqid();
1642
1643
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1644
1645
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1646
        $commentAdmin->setParentAssociationMapping('post.author');
1647
        $commentAdmin->setParent($postAdmin);
1648
1649
        $request = $this->createMock(Request::class);
1650
        $query = $this->createMock(ParameterBag::class);
1651
        $query
1652
            ->method('get')
1653
            ->willReturn([
1654
                'filter' => [
1655
                    '_page' => '1',
1656
                    '_per_page' => '32',
1657
                ],
1658
            ]);
1659
1660
        $request->query = $query;
1661
        $request
1662
            ->method('get')
1663
            ->willReturn($authorId);
1664
1665
        $commentAdmin->setRequest($request);
1666
1667
        $modelManager = $this->createMock(ModelManagerInterface::class);
1668
        $modelManager
1669
            ->method('getDefaultSortValues')
1670
            ->willReturn([]);
1671
1672
        $commentAdmin->setModelManager($modelManager);
1673
1674
        $parameters = $commentAdmin->getFilterParameters();
1675
1676
        $this->assertTrue(isset($parameters['post__author']));
1677
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1678
    }
1679
1680
    public function testGetFilterFieldDescription(): void
1681
    {
1682
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1683
1684
        $fooFieldDescription = new FieldDescription();
1685
        $barFieldDescription = new FieldDescription();
1686
        $bazFieldDescription = new FieldDescription();
1687
1688
        $modelManager = $this->createMock(ModelManagerInterface::class);
1689
        $modelManager->expects($this->exactly(3))
1690
            ->method('getNewFieldDescriptionInstance')
1691
            ->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...
1692
                switch ($name) {
1693
                    case 'foo':
1694
                        $fieldDescription = $fooFieldDescription;
1695
1696
                        break;
1697
1698
                    case 'bar':
1699
                        $fieldDescription = $barFieldDescription;
1700
1701
                        break;
1702
1703
                    case 'baz':
1704
                        $fieldDescription = $bazFieldDescription;
1705
1706
                        break;
1707
1708
                    default:
1709
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1710
                        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...
1711
                }
1712
1713
                $fieldDescription->setName($name);
1714
1715
                return $fieldDescription;
1716
            });
1717
1718
        $modelAdmin->setModelManager($modelManager);
1719
1720
        $pager = $this->createMock(PagerInterface::class);
1721
1722
        $datagrid = $this->createMock(DatagridInterface::class);
1723
        $datagrid->expects($this->once())
1724
            ->method('getPager')
1725
            ->willReturn($pager);
1726
1727
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1728
        $datagridBuilder->expects($this->once())
1729
            ->method('getBaseDatagrid')
1730
            ->with($this->identicalTo($modelAdmin), [])
1731
            ->willReturn($datagrid);
1732
1733
        $datagridBuilder->expects($this->exactly(3))
1734
            ->method('addFilter')
1735
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1736
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1737
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1738
            });
1739
1740
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1741
1742
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1743
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1744
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1745
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1746
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1747
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1748
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1749
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1750
    }
1751
1752
    public function testGetSubjectNoRequest(): void
1753
    {
1754
        $modelManager = $this->createMock(ModelManagerInterface::class);
1755
        $modelManager
1756
            ->expects($this->never())
1757
            ->method('find');
1758
1759
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1760
        $admin->setModelManager($modelManager);
1761
1762
        $this->assertFalse($admin->hasSubject());
1763
    }
1764
1765
    public function testGetSideMenu(): void
1766
    {
1767
        $item = $this->createMock(ItemInterface::class);
1768
        $item
1769
            ->expects($this->once())
1770
            ->method('setChildrenAttribute')
1771
            ->with('class', 'nav navbar-nav');
1772
        $item
1773
            ->expects($this->once())
1774
            ->method('setExtra')
1775
            ->with('translation_domain', 'foo_bar_baz');
1776
1777
        $menuFactory = $this->createMock(FactoryInterface::class);
1778
        $menuFactory
1779
            ->expects($this->once())
1780
            ->method('createItem')
1781
            ->willReturn($item);
1782
1783
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1784
        $modelAdmin->setMenuFactory($menuFactory);
1785
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1786
1787
        $modelAdmin->getSideMenu('foo');
1788
    }
1789
1790
    /**
1791
     * @return array
1792
     */
1793
    public function provideGetSubject()
1794
    {
1795
        return [
1796
            [23],
1797
            ['azerty'],
1798
            ['4f69bbb5f14a13347f000092'],
1799
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1800
            ['123'.AdapterInterface::ID_SEPARATOR.'my_type'], // composite keys are supported
1801
        ];
1802
    }
1803
1804
    /**
1805
     * @dataProvider provideGetSubject
1806
     */
1807
    public function testGetSubjectFailed($id): void
1808
    {
1809
        $modelManager = $this->createMock(ModelManagerInterface::class);
1810
        $modelManager
1811
            ->expects($this->once())
1812
            ->method('find')
1813
            ->with('NewsBundle\Entity\Post', $id)
1814
            ->willReturn(null); // entity not found
1815
1816
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1817
        $admin->setModelManager($modelManager);
1818
1819
        $admin->setRequest(new Request(['id' => $id]));
1820
        $this->assertFalse($admin->hasSubject());
1821
    }
1822
1823
    /**
1824
     * @dataProvider provideGetSubject
1825
     */
1826
    public function testGetSubject($id): void
1827
    {
1828
        $model = new Post();
1829
1830
        $modelManager = $this->createMock(ModelManagerInterface::class);
1831
        $modelManager
1832
            ->expects($this->once())
1833
            ->method('find')
1834
            ->with('NewsBundle\Entity\Post', $id)
1835
            ->willReturn($model);
1836
1837
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1838
        $admin->setModelManager($modelManager);
1839
1840
        $admin->setRequest(new Request(['id' => $id]));
1841
        $this->assertTrue($admin->hasSubject());
1842
        $this->assertSame($model, $admin->getSubject());
1843
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
1844
    }
1845
1846
    public function testGetSubjectWithParentDescription(): void
1847
    {
1848
        $adminId = 1;
1849
1850
        $comment = new Comment();
1851
1852
        $modelManager = $this->createMock(ModelManagerInterface::class);
1853
        $modelManager
1854
            ->method('find')
1855
            ->with('NewsBundle\Entity\Comment', $adminId)
1856
            ->willReturn($comment);
1857
1858
        $request = new Request(['id' => $adminId]);
1859
1860
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1861
        $postAdmin->setRequest($request);
1862
1863
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1864
        $commentAdmin->setRequest($request);
1865
        $commentAdmin->setModelManager($modelManager);
1866
1867
        $this->assertTrue($commentAdmin->hasSubject());
1868
        $this->assertSame($comment, $commentAdmin->getSubject());
1869
1870
        $commentAdmin->setSubject(null);
1871
        $commentAdmin->setParentFieldDescription(new FieldDescription());
1872
1873
        $this->assertFalse($commentAdmin->hasSubject());
1874
    }
1875
1876
    /**
1877
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1878
     */
1879
    public function testGetActionButtonsList(): void
1880
    {
1881
        $expected = [
1882
            'create' => [
1883
                'template' => 'Foo.html.twig',
1884
            ],
1885
        ];
1886
1887
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1888
1889
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1890
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
1891
1892
        $admin->setTemplateRegistry($templateRegistry->reveal());
1893
1894
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1895
        $securityHandler
1896
            ->expects($this->once())
1897
            ->method('isGranted')
1898
            ->with($admin, 'CREATE', $admin)
1899
            ->willReturn(true);
1900
        $admin->setSecurityHandler($securityHandler);
1901
1902
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1903
        $routeGenerator
1904
            ->expects($this->once())
1905
            ->method('hasAdminRoute')
1906
            ->with($admin, 'create')
1907
            ->willReturn(true);
1908
        $admin->setRouteGenerator($routeGenerator);
1909
1910
        $this->assertSame($expected, $admin->getActionButtons('list', null));
1911
    }
1912
1913
    /**
1914
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1915
     */
1916
    public function testGetActionButtonsListCreateDisabled(): void
1917
    {
1918
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1919
1920
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1921
        $securityHandler
1922
            ->expects($this->once())
1923
            ->method('isGranted')
1924
            ->with($admin, 'CREATE', $admin)
1925
            ->willReturn(false);
1926
        $admin->setSecurityHandler($securityHandler);
1927
1928
        $this->assertSame([], $admin->getActionButtons('list', null));
1929
    }
1930
1931
    /**
1932
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
1933
     */
1934
    public function testGetBatchActions(): void
1935
    {
1936
        $expected = [
1937
            'delete' => [
1938
                'label' => 'action_delete',
1939
                'translation_domain' => 'SonataAdminBundle',
1940
                'ask_confirmation' => true, // by default always true
1941
            ],
1942
            'foo' => [
1943
                'label' => 'action_foo',
1944
                'translation_domain' => 'SonataAdminBundle',
1945
            ],
1946
            'bar' => [
1947
                'label' => 'batch.label_bar',
1948
                'translation_domain' => 'SonataAdminBundle',
1949
            ],
1950
            'baz' => [
1951
                'label' => 'action_baz',
1952
                'translation_domain' => 'AcmeAdminBundle',
1953
            ],
1954
        ];
1955
1956
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
1957
1958
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1959
        $labelTranslatorStrategy
1960
            ->method('getLabel')
1961
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
1962
                return $context.'.'.$type.'_'.$label;
1963
            });
1964
1965
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1966
        $admin->setRouteBuilder($pathInfo);
1967
        $admin->setTranslationDomain('SonataAdminBundle');
1968
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1969
1970
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1971
        $routeGenerator
1972
            ->expects($this->once())
1973
            ->method('hasAdminRoute')
1974
            ->with($admin, 'delete')
1975
            ->willReturn(true);
1976
        $admin->setRouteGenerator($routeGenerator);
1977
1978
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1979
        $securityHandler
1980
            ->method('isGranted')
1981
            ->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...
1982
                return $admin === $adminIn && 'DELETE' === $attributes;
1983
            });
1984
        $admin->setSecurityHandler($securityHandler);
1985
1986
        $this->assertSame($expected, $admin->getBatchActions());
1987
    }
1988
1989
    /**
1990
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
1991
     */
1992
    public function testShowMosaicButton(): void
1993
    {
1994
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1995
        $listModes = $admin->getListModes();
1996
1997
        $admin->showMosaicButton(true);
1998
1999
        $this->assertSame($listModes, $admin->getListModes());
2000
    }
2001
2002
    /**
2003
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2004
     */
2005
    public function testShowMosaicButtonHideMosaic(): void
2006
    {
2007
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2008
        $listModes = $admin->getListModes();
2009
        $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...
2010
2011
        $admin->showMosaicButton(false);
2012
2013
        $this->assertSame($expected, $admin->getListModes());
2014
    }
2015
2016
    /**
2017
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2018
     * @dataProvider provideGetBaseRouteName
2019
     */
2020
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2021
    {
2022
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2023
        $routerMock = $this->createMock(RouterInterface::class);
2024
2025
        $routerMock->method('generate')->willReturn('/admin/post');
2026
2027
        $routeGenerator = new DefaultRouteGenerator(
2028
            $routerMock,
2029
            new RoutesCache($this->cacheTempFolder, true)
2030
        );
2031
2032
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
2033
        $admin->setRouteBuilder($pathInfo);
2034
        $admin->setRouteGenerator($routeGenerator);
2035
        $admin->initialize();
2036
2037
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2038
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2039
2040
        $admin->setTemplateRegistry($templateRegistry->reveal());
2041
2042
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2043
        $securityHandler
2044
            ->method('isGranted')
2045
            ->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...
2046
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2047
            });
2048
2049
        $admin->setSecurityHandler($securityHandler);
2050
2051
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2052
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2053
    }
2054
2055
    public function testDefaultFilters(): void
2056
    {
2057
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2058
2059
        $subjectId = uniqid();
2060
2061
        $request = $this->createMock(Request::class);
2062
        $query = $this->createMock(ParameterBag::class);
2063
        $query
2064
            ->method('get')
2065
            ->with($this->equalTo('filter'))
2066
            ->willReturn([
2067
                'a' => [
2068
                    'value' => 'b',
2069
                ],
2070
                'foo' => [
2071
                    'type' => '1',
2072
                    'value' => 'bar',
2073
                ],
2074
                'baz' => [
2075
                    'type' => '5',
2076
                    'value' => 'test',
2077
                ],
2078
            ]);
2079
        $request->query = $query;
2080
2081
        $request
2082
            ->method('get')
2083
            ->willReturn($subjectId);
2084
2085
        $admin->setRequest($request);
2086
2087
        $modelManager = $this->createMock(ModelManagerInterface::class);
2088
        $modelManager
2089
            ->method('getDefaultSortValues')
2090
            ->willReturn([]);
2091
2092
        $admin->setModelManager($modelManager);
2093
2094
        $this->assertSame([
2095
            '_page' => 1,
2096
            '_per_page' => 32,
2097
            'foo' => [
2098
                'type' => '1',
2099
                'value' => 'bar',
2100
            ],
2101
            'baz' => [
2102
                'type' => '5',
2103
                'value' => 'test',
2104
            ],
2105
            'a' => [
2106
                'value' => 'b',
2107
            ],
2108
        ], $admin->getFilterParameters());
2109
2110
        $this->assertTrue($admin->isDefaultFilter('foo'));
2111
        $this->assertFalse($admin->isDefaultFilter('bar'));
2112
        $this->assertFalse($admin->isDefaultFilter('a'));
2113
    }
2114
2115
    /**
2116
     * NEXT_MAJOR: remove this method.
2117
     *
2118
     * @group legacy
2119
     */
2120
    public function testCreateQueryLegacyCallWorks(): void
2121
    {
2122
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2123
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2124
        ]);
2125
        $query = $this->createMock(ProxyQueryInterface::class);
2126
        $modelManager = $this->createMock(ModelManagerInterface::class);
2127
        $modelManager->expects($this->once())
2128
            ->method('createQuery')
2129
            ->with('My\Class')
2130
            ->willReturn($query);
2131
2132
        $admin->setModelManager($modelManager);
2133
        $this->assertSame($query, $admin->createQuery('list'));
2134
    }
2135
2136
    public function testGetDataSourceIterator(): void
2137
    {
2138
        $datagrid = $this->createMock(DatagridInterface::class);
2139
        $datagrid->method('buildPager');
2140
2141
        $modelManager = $this->createMock(ModelManagerInterface::class);
2142
        $modelManager->method('getExportFields')->willReturn([
2143
            'field',
2144
            'foo',
2145
            'bar',
2146
        ]);
2147
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2148
            ->with($this->equalTo($datagrid), $this->equalTo([
2149
                'Feld' => 'field',
2150
                1 => 'foo',
2151
                2 => 'bar',
2152
            ]))
2153
            ->willReturn(new ArraySourceIterator([]));
2154
2155
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2156
            ->disableOriginalConstructor()
2157
            ->setMethods(['getClass', 'getDatagrid', 'getTranslationLabel', 'trans'])
2158
            ->getMockForAbstractClass();
2159
        $admin->method('getClass')->willReturn('App\Admin\MyAdmin');
2160
        $admin->method('getDatagrid')->willReturn($datagrid);
2161
        $admin->setModelManager($modelManager);
2162
2163
        $admin
2164
            ->method('getTranslationLabel')
2165
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2166
                return $context.'.'.$type.'_'.$label;
2167
            });
2168
        $admin
2169
            ->method('trans')
2170
            ->willReturnCallback(static function (string $label): string {
2171
                if ('export.label_field' === $label) {
2172
                    return 'Feld';
2173
                }
2174
2175
                return $label;
2176
            });
2177
2178
        $admin->getDataSourceIterator();
2179
    }
2180
2181
    public function testCircularChildAdmin(): void
2182
    {
2183
        $this->expectException(\RuntimeException::class);
2184
        $this->expectExceptionMessage(
2185
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2186
        );
2187
2188
        $postAdmin = new PostAdmin(
2189
            'sonata.post.admin.post',
2190
            'Application\Sonata\NewsBundle\Entity\Post',
2191
            'Sonata\NewsBundle\Controller\PostAdminController'
2192
        );
2193
        $commentAdmin = new CommentAdmin(
2194
            'sonata.post.admin.comment',
2195
            'Application\Sonata\NewsBundle\Entity\Comment',
2196
            'Sonata\NewsBundle\Controller\CommentAdminController'
2197
        );
2198
        $postAdmin->addChild($commentAdmin, 'post');
2199
        $commentAdmin->addChild($postAdmin, 'comment');
2200
    }
2201
2202
    public function testCircularChildAdminTripleLevel(): void
2203
    {
2204
        $this->expectException(\RuntimeException::class);
2205
        $this->expectExceptionMessage(
2206
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2207
        );
2208
2209
        $postAdmin = new PostAdmin(
2210
            'sonata.post.admin.post',
2211
            'Application\Sonata\NewsBundle\Entity\Post',
2212
            'Sonata\NewsBundle\Controller\PostAdminController'
2213
        );
2214
        $commentAdmin = new CommentAdmin(
2215
            'sonata.post.admin.comment',
2216
            'Application\Sonata\NewsBundle\Entity\Comment',
2217
            'Sonata\NewsBundle\Controller\CommentAdminController'
2218
        );
2219
        $commentVoteAdmin = new CommentVoteAdmin(
2220
            'sonata.post.admin.comment_vote',
2221
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2222
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2223
        );
2224
        $postAdmin->addChild($commentAdmin, 'post');
2225
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2226
        $commentVoteAdmin->addChild($postAdmin, 'post');
2227
    }
2228
2229
    public function testCircularChildAdminWithItself(): void
2230
    {
2231
        $this->expectException(\RuntimeException::class);
2232
        $this->expectExceptionMessage(
2233
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2234
        );
2235
2236
        $postAdmin = new PostAdmin(
2237
            'sonata.post.admin.post',
2238
            'Application\Sonata\NewsBundle\Entity\Post',
2239
            'Sonata\NewsBundle\Controller\PostAdminController'
2240
        );
2241
        $postAdmin->addChild($postAdmin);
2242
    }
2243
2244
    public function testGetRootAncestor(): void
2245
    {
2246
        $postAdmin = new PostAdmin(
2247
            'sonata.post.admin.post',
2248
            'Application\Sonata\NewsBundle\Entity\Post',
2249
            'Sonata\NewsBundle\Controller\PostAdminController'
2250
        );
2251
        $commentAdmin = new CommentAdmin(
2252
            'sonata.post.admin.comment',
2253
            'Application\Sonata\NewsBundle\Entity\Comment',
2254
            'Sonata\NewsBundle\Controller\CommentAdminController'
2255
        );
2256
        $commentVoteAdmin = new CommentVoteAdmin(
2257
            'sonata.post.admin.comment_vote',
2258
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2259
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2260
        );
2261
2262
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2263
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2264
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2265
2266
        $postAdmin->addChild($commentAdmin, 'post');
2267
2268
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2269
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2270
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2271
2272
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2273
2274
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2275
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2276
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2277
    }
2278
2279
    public function testGetChildDepth(): void
2280
    {
2281
        $postAdmin = new PostAdmin(
2282
            'sonata.post.admin.post',
2283
            'Application\Sonata\NewsBundle\Entity\Post',
2284
            'Sonata\NewsBundle\Controller\PostAdminController'
2285
        );
2286
        $commentAdmin = new CommentAdmin(
2287
            'sonata.post.admin.comment',
2288
            'Application\Sonata\NewsBundle\Entity\Comment',
2289
            'Sonata\NewsBundle\Controller\CommentAdminController'
2290
        );
2291
        $commentVoteAdmin = new CommentVoteAdmin(
2292
            'sonata.post.admin.comment_vote',
2293
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2294
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2295
        );
2296
2297
        $this->assertSame(0, $postAdmin->getChildDepth());
2298
        $this->assertSame(0, $commentAdmin->getChildDepth());
2299
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2300
2301
        $postAdmin->addChild($commentAdmin, 'post');
2302
2303
        $this->assertSame(0, $postAdmin->getChildDepth());
2304
        $this->assertSame(1, $commentAdmin->getChildDepth());
2305
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2306
2307
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2308
2309
        $this->assertSame(0, $postAdmin->getChildDepth());
2310
        $this->assertSame(1, $commentAdmin->getChildDepth());
2311
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2312
    }
2313
2314
    public function testGetCurrentLeafChildAdmin(): void
2315
    {
2316
        $postAdmin = new PostAdmin(
2317
            'sonata.post.admin.post',
2318
            'Application\Sonata\NewsBundle\Entity\Post',
2319
            'Sonata\NewsBundle\Controller\PostAdminController'
2320
        );
2321
        $commentAdmin = new CommentAdmin(
2322
            'sonata.post.admin.comment',
2323
            'Application\Sonata\NewsBundle\Entity\Comment',
2324
            'Sonata\NewsBundle\Controller\CommentAdminController'
2325
        );
2326
        $commentVoteAdmin = new CommentVoteAdmin(
2327
            'sonata.post.admin.comment_vote',
2328
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2329
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2330
        );
2331
2332
        $postAdmin->addChild($commentAdmin, 'post');
2333
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2334
2335
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2336
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2337
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2338
2339
        $commentAdmin->setCurrentChild(true);
2340
2341
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2342
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2343
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2344
2345
        $commentVoteAdmin->setCurrentChild(true);
2346
2347
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2348
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2349
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2350
    }
2351
2352
    public function testAdminAvoidInifiniteLoop(): void
2353
    {
2354
        $this->expectNotToPerformAssertions();
2355
2356
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2357
2358
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2359
        $admin->setSubject(new \stdClass());
2360
2361
        $admin->setFormContractor(new FormContractor($formFactory));
2362
2363
        $admin->setShowBuilder(new ShowBuilder());
2364
2365
        $admin->setListBuilder(new ListBuilder());
2366
2367
        $pager = $this->createStub(PagerInterface::class);
2368
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2369
2370
        $validator = $this->createMock(ValidatorInterface::class);
2371
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2372
        $admin->setValidator($validator);
2373
2374
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2375
        $routeGenerator->method('hasAdminRoute')->willReturn(false);
2376
        $admin->setRouteGenerator($routeGenerator);
2377
2378
        $admin->getForm();
2379
        $admin->getShow();
2380
        $admin->getList();
2381
        $admin->getDatagrid();
2382
    }
2383
2384
    private function createTagAdmin(Post $post): TagAdmin
2385
    {
2386
        $postAdmin = $this->getMockBuilder(PostAdmin::class)
2387
            ->disableOriginalConstructor()
2388
            ->getMock();
2389
2390
        $postAdmin->method('getObject')->willReturn($post);
2391
2392
        $formBuilder = $this->createMock(FormBuilderInterface::class);
2393
        $formBuilder->method('getForm')->willReturn(null);
2394
2395
        $tagAdmin = $this->getMockBuilder(TagAdmin::class)
2396
            ->setConstructorArgs([
2397
                'admin.tag',
2398
                Tag::class,
2399
                'MyBundle\MyController',
2400
            ])
2401
            ->setMethods(['getFormBuilder'])
2402
            ->getMock();
2403
2404
        $tagAdmin->method('getFormBuilder')->willReturn($formBuilder);
2405
        $tagAdmin->setParent($postAdmin);
2406
2407
        $tag = new Tag();
2408
        $tagAdmin->setSubject($tag);
2409
2410
        $request = $this->createMock(Request::class);
2411
        $tagAdmin->setRequest($request);
2412
2413
        $configurationPool = $this->getMockBuilder(Pool::class)
2414
            ->disableOriginalConstructor()
2415
            ->getMock();
2416
2417
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
2418
2419
        $tagAdmin->setConfigurationPool($configurationPool);
2420
2421
        return $tagAdmin;
2422
    }
2423
}
2424