Completed
Push — master ( 651a01...276b19 )
by Grégoire
03:01
created

AdminTest::getDeprecatedAbstractAdminConstructorArgs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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