Completed
Push — 3.x ( 467a14...d51665 )
by Oskar
02:57
created

testGetBaseRoutePatternWithUnreconizedClassname()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Tests\Admin;
15
16
use Doctrine\Common\Collections\Collection;
17
use Knp\Menu\FactoryInterface;
18
use Knp\Menu\ItemInterface;
19
use PHPUnit\Framework\TestCase;
20
use Sonata\AdminBundle\Admin\AbstractAdmin;
21
use Sonata\AdminBundle\Admin\AbstractAdminExtension;
22
use Sonata\AdminBundle\Admin\AdminExtensionInterface;
23
use Sonata\AdminBundle\Admin\AdminInterface;
24
use Sonata\AdminBundle\Admin\BreadcrumbsBuilder;
25
use Sonata\AdminBundle\Admin\BreadcrumbsBuilderInterface;
26
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
27
use Sonata\AdminBundle\Admin\Pool;
28
use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
29
use Sonata\AdminBundle\Builder\FormContractorInterface;
30
use Sonata\AdminBundle\Builder\ListBuilderInterface;
31
use Sonata\AdminBundle\Builder\RouteBuilderInterface;
32
use Sonata\AdminBundle\Builder\ShowBuilderInterface;
33
use Sonata\AdminBundle\Datagrid\DatagridInterface;
34
use Sonata\AdminBundle\Datagrid\PagerInterface;
35
use Sonata\AdminBundle\Filter\Persister\FilterPersisterInterface;
36
use Sonata\AdminBundle\Model\AuditManagerInterface;
37
use Sonata\AdminBundle\Model\ModelManagerInterface;
38
use Sonata\AdminBundle\Route\DefaultRouteGenerator;
39
use Sonata\AdminBundle\Route\PathInfoBuilder;
40
use Sonata\AdminBundle\Route\RouteGeneratorInterface;
41
use Sonata\AdminBundle\Route\RoutesCache;
42
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
43
use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface;
44
use Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface;
45
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentAdmin;
46
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentVoteAdmin;
47
use Sonata\AdminBundle\Tests\Fixtures\Admin\CommentWithCustomRouteAdmin;
48
use Sonata\AdminBundle\Tests\Fixtures\Admin\FieldDescription;
49
use Sonata\AdminBundle\Tests\Fixtures\Admin\FilteredAdmin;
50
use Sonata\AdminBundle\Tests\Fixtures\Admin\ModelAdmin;
51
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin;
52
use Sonata\AdminBundle\Tests\Fixtures\Admin\PostWithCustomRouteAdmin;
53
use Sonata\AdminBundle\Tests\Fixtures\Admin\TagAdmin;
54
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\BlogPost;
55
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Comment;
56
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Post;
57
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Tag;
58
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
59
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToStringNull;
60
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
61
use Sonata\Doctrine\Adapter\AdapterInterface;
62
use Symfony\Component\DependencyInjection\Container;
63
use Symfony\Component\DependencyInjection\ContainerInterface;
64
use Symfony\Component\Filesystem\Filesystem;
65
use Symfony\Component\Form\FormBuilder;
66
use Symfony\Component\Form\FormBuilderInterface;
67
use Symfony\Component\Form\FormEvent;
68
use Symfony\Component\Form\FormEvents;
69
use Symfony\Component\HttpFoundation\ParameterBag;
70
use Symfony\Component\HttpFoundation\Request;
71
use Symfony\Component\PropertyAccess\PropertyAccess;
72
use Symfony\Component\Routing\RouterInterface;
73
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
74
use Symfony\Component\Translation\TranslatorInterface;
75
use Symfony\Component\Validator\Mapping\MemberMetadata;
76
use Symfony\Component\Validator\Validator\ValidatorInterface;
77
78
class AdminTest extends TestCase
79
{
80
    protected $cacheTempFolder;
81
82
    public function setUp(): void
83
    {
84
        $this->cacheTempFolder = sys_get_temp_dir().'/sonata_test_route';
85
        $filesystem = new Filesystem();
86
        $filesystem->remove($this->cacheTempFolder);
87
    }
88
89
    /**
90
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::__construct
91
     */
92
    public function testConstructor(): void
93
    {
94
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
95
        $baseControllerName = 'SonataNewsBundle:PostAdmin';
96
97
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
98
        $this->assertInstanceOf(AbstractAdmin::class, $admin);
99
        $this->assertSame($class, $admin->getClass());
100
        $this->assertSame($baseControllerName, $admin->getBaseControllerName());
101
    }
102
103
    public function testGetClass(): void
104
    {
105
        $class = Post::class;
106
        $baseControllerName = 'SonataNewsBundle:PostAdmin';
107
108
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
109
110
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
111
112
        $admin->setSubject(new BlogPost());
113
        $this->assertSame(BlogPost::class, $admin->getClass());
114
115
        $admin->setSubClasses(['foo']);
116
        $this->assertSame(BlogPost::class, $admin->getClass());
117
118
        $admin->setSubject(null);
119
        $admin->setSubClasses([]);
120
        $this->assertSame($class, $admin->getClass());
121
122
        $admin->setSubClasses(['foo' => 'bar']);
123
        $admin->setRequest(new Request(['subclass' => 'foo']));
124
        $this->assertSame('bar', $admin->getClass());
125
    }
126
127
    public function testGetClassException(): void
128
    {
129
        $this->expectException(\RuntimeException::class);
130
        $this->expectExceptionMessage('Feature not implemented: an embedded admin cannot have subclass');
131
132
        $class = 'Application\Sonata\NewsBundle\Entity\Post';
133
        $baseControllerName = 'SonataNewsBundle:PostAdmin';
134
135
        $admin = new PostAdmin('sonata.post.admin.post', $class, $baseControllerName);
136
        $admin->setParentFieldDescription(new FieldDescription());
137
        $admin->setSubClasses(['foo' => 'bar']);
138
        $admin->setRequest(new Request(['subclass' => 'foo']));
139
        $admin->getClass();
140
    }
141
142
    public function testCheckAccessThrowsExceptionOnMadeUpAction(): void
143
    {
144
        $admin = new PostAdmin(
145
            'sonata.post.admin.post',
146
            'Application\Sonata\NewsBundle\Entity\Post',
147
            'SonataNewsBundle:PostAdmin'
148
        );
149
        $this->expectException(
150
            \InvalidArgumentException::class
151
        );
152
        $this->expectExceptionMessage(
153
            'Action "made-up" could not be found'
154
        );
155
        $admin->checkAccess('made-up');
156
    }
157
158
    public function testCheckAccessThrowsAccessDeniedException(): void
159
    {
160
        $admin = new PostAdmin(
161
            'sonata.post.admin.post',
162
            'Application\Sonata\NewsBundle\Entity\Post',
163
            'SonataNewsBundle:PostAdmin'
164
        );
165
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
166
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
167
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
168
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
169
        $customExtension->getAccessMapping($admin)->willReturn(
170
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
171
        );
172
        $admin->addExtension($customExtension->reveal());
173
        $admin->setSecurityHandler($securityHandler->reveal());
174
        $this->expectException(
175
            AccessDeniedException::class
176
        );
177
        $this->expectExceptionMessage(
178
            'Access Denied to the action custom_action and role EXTRA_CUSTOM_ROLE'
179
        );
180
        $admin->checkAccess('custom_action');
181
    }
182
183
    public function testHasAccessOnMadeUpAction(): void
184
    {
185
        $admin = new PostAdmin(
186
            'sonata.post.admin.post',
187
            'Application\Sonata\NewsBundle\Entity\Post',
188
            'SonataNewsBundle:PostAdmin'
189
        );
190
191
        $this->assertFalse($admin->hasAccess('made-up'));
192
    }
193
194
    public function testHasAccess(): void
195
    {
196
        $admin = new PostAdmin(
197
            'sonata.post.admin.post',
198
            'Application\Sonata\NewsBundle\Entity\Post',
199
            'SonataNewsBundle:PostAdmin'
200
        );
201
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
202
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
203
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(false);
204
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
205
        $customExtension->getAccessMapping($admin)->willReturn(
206
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
207
        );
208
        $admin->addExtension($customExtension->reveal());
209
        $admin->setSecurityHandler($securityHandler->reveal());
210
211
        $this->assertFalse($admin->hasAccess('custom_action'));
212
    }
213
214
    public function testHasAccessAllowsAccess(): void
215
    {
216
        $admin = new PostAdmin(
217
            'sonata.post.admin.post',
218
            'Application\Sonata\NewsBundle\Entity\Post',
219
            'SonataNewsBundle:PostAdmin'
220
        );
221
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
222
        $securityHandler->isGranted($admin, 'CUSTOM_ROLE', $admin)->willReturn(true);
223
        $securityHandler->isGranted($admin, 'EXTRA_CUSTOM_ROLE', $admin)->willReturn(true);
224
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
225
        $customExtension->getAccessMapping($admin)->willReturn(
226
            ['custom_action' => ['CUSTOM_ROLE', 'EXTRA_CUSTOM_ROLE']]
227
        );
228
        $admin->addExtension($customExtension->reveal());
229
        $admin->setSecurityHandler($securityHandler->reveal());
230
231
        $this->assertTrue($admin->hasAccess('custom_action'));
232
    }
233
234
    public function testHasAccessAllowsAccessEditAction(): void
235
    {
236
        $admin = new PostAdmin(
237
            'sonata.post.admin.post',
238
            'Application\Sonata\NewsBundle\Entity\Post',
239
            'SonataNewsBundle:PostAdmin'
240
        );
241
        $securityHandler = $this->prophesize(SecurityHandlerInterface::class);
242
        $securityHandler->isGranted($admin, 'EDIT_ROLE', $admin)->willReturn(true);
243
        $customExtension = $this->prophesize(AbstractAdminExtension::class);
244
        $customExtension->getAccessMapping($admin)->willReturn(
245
            ['edit_action' => ['EDIT_ROLE']]
246
        );
247
        $admin->addExtension($customExtension->reveal());
248
        $admin->setSecurityHandler($securityHandler->reveal());
249
250
        $this->assertTrue($admin->hasAccess('edit_action'));
251
    }
252
253
    /**
254
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChild
255
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::addChild
256
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChild
257
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::isChild
258
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasChildren
259
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getChildren
260
     */
261
    public function testChildren(): void
262
    {
263
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
264
        $this->assertFalse($postAdmin->hasChildren());
265
        $this->assertFalse($postAdmin->hasChild('comment'));
266
267
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
268
        $postAdmin->addChild($commentAdmin, 'post');
269
270
        $this->assertTrue($postAdmin->hasChildren());
271
        $this->assertTrue($postAdmin->hasChild('sonata.post.admin.comment'));
272
273
        $this->assertSame('sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getCode());
274
        $this->assertSame('sonata.post.admin.post|sonata.post.admin.comment', $postAdmin->getChild('sonata.post.admin.comment')->getBaseCodeRoute());
275
        $this->assertSame($postAdmin, $postAdmin->getChild('sonata.post.admin.comment')->getParent());
276
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
277
278
        $this->assertFalse($postAdmin->isChild());
279
        $this->assertTrue($commentAdmin->isChild());
280
281
        $this->assertSame(['sonata.post.admin.comment' => $commentAdmin], $postAdmin->getChildren());
282
    }
283
284
    /**
285
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configure
286
     */
287
    public function testConfigure(): void
288
    {
289
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
290
        $this->assertNotNull($admin->getUniqid());
291
292
        $admin->initialize();
293
        $this->assertNotNull($admin->getUniqid());
294
        $this->assertSame('Post', $admin->getClassnameLabel());
295
296
        $admin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
297
        $admin->setClassnameLabel('postcomment');
298
299
        $admin->initialize();
300
        $this->assertSame('postcomment', $admin->getClassnameLabel());
301
    }
302
303
    public function testConfigureWithValidParentAssociationMapping(): void
304
    {
305
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
306
        $admin->setParentAssociationMapping('Category');
307
308
        $admin->initialize();
309
        $this->assertSame('Category', $admin->getParentAssociationMapping());
310
    }
311
312
    public function provideGetBaseRoutePattern()
313
    {
314
        return [
315
            [
316
                'Application\Sonata\NewsBundle\Entity\Post',
317
                '/sonata/news/post',
318
            ],
319
            [
320
                'Application\Sonata\NewsBundle\Document\Post',
321
                '/sonata/news/post',
322
            ],
323
            [
324
                'MyApplication\MyBundle\Entity\Post',
325
                '/myapplication/my/post',
326
            ],
327
            [
328
                'MyApplication\MyBundle\Entity\Post\Category',
329
                '/myapplication/my/post-category',
330
            ],
331
            [
332
                'MyApplication\MyBundle\Entity\Product\Category',
333
                '/myapplication/my/product-category',
334
            ],
335
            [
336
                'MyApplication\MyBundle\Entity\Other\Product\Category',
337
                '/myapplication/my/other-product-category',
338
            ],
339
            [
340
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
341
                '/cmf/foo/menu',
342
            ],
343
            [
344
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
345
                '/cmf/foo/menu',
346
            ],
347
            [
348
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
349
                '/symfony/barbar/menu',
350
            ],
351
            [
352
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
353
                '/symfony/barbar/menu-item',
354
            ],
355
            [
356
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
357
                '/cmf/foo/menu',
358
            ],
359
            [
360
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
361
                '/cmf/foo/menu',
362
            ],
363
            [
364
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
365
                '/cmf/foo/menu',
366
            ],
367
            [
368
                'AppBundle\Entity\User',
369
                '/app/user',
370
            ],
371
            [
372
                'App\Entity\User',
373
                '/app/user',
374
            ],
375
        ];
376
    }
377
378
    /**
379
     * @dataProvider provideGetBaseRoutePattern
380
     */
381
    public function testGetBaseRoutePattern(string $objFqn, string $expected): void
382
    {
383
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
384
        $this->assertSame($expected, $admin->getBaseRoutePattern());
385
    }
386
387
    /**
388
     * @dataProvider provideGetBaseRoutePattern
389
     */
390
    public function testGetBaseRoutePatternWithChildAdmin(string $objFqn, string $expected): void
391
    {
392
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
393
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
394
        $commentAdmin->setParent($postAdmin);
395
396
        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
397
    }
398
399
    /**
400
     * @dataProvider provideGetBaseRoutePattern
401
     */
402
    public function testGetBaseRoutePatternWithTwoNestedChildAdmin(string $objFqn, string $expected): void
403
    {
404
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
405
        $commentAdmin = new CommentAdmin(
406
            'sonata.post.admin.comment',
407
            'Application\Sonata\NewsBundle\Entity\Comment',
408
            'SonataNewsBundle:CommentAdmin'
409
        );
410
        $commentVoteAdmin = new CommentVoteAdmin(
411
            'sonata.post.admin.comment_vote',
412
            'Application\Sonata\NewsBundle\Entity\CommentVote',
413
            'SonataNewsBundle:CommentVoteAdmin'
414
        );
415
        $commentAdmin->setParent($postAdmin);
416
        $commentVoteAdmin->setParent($commentAdmin);
417
418
        $this->assertSame($expected.'/{id}/comment/{childId}/commentvote', $commentVoteAdmin->getBaseRoutePattern());
419
    }
420
421
    public function testGetBaseRoutePatternWithSpecifedPattern(): void
422
    {
423
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostWithCustomRouteAdmin');
424
425
        $this->assertSame('/post-custom', $postAdmin->getBaseRoutePattern());
426
    }
427
428
    public function testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern(): void
429
    {
430
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
431
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentWithCustomRouteAdmin');
432
        $commentAdmin->setParent($postAdmin);
433
434
        $this->assertSame('/sonata/news/post/{id}/comment-custom', $commentAdmin->getBaseRoutePattern());
435
    }
436
437
    public function testGetBaseRoutePatternWithUnreconizedClassname(): void
438
    {
439
        $this->expectException(\RuntimeException::class);
440
441
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'SonataNewsBundle:PostAdmin');
442
        $admin->getBaseRoutePattern();
443
    }
444
445
    public function provideGetBaseRouteName()
446
    {
447
        return [
448
            [
449
                'Application\Sonata\NewsBundle\Entity\Post',
450
                'admin_sonata_news_post',
451
            ],
452
            [
453
                'Application\Sonata\NewsBundle\Document\Post',
454
                'admin_sonata_news_post',
455
            ],
456
            [
457
                'MyApplication\MyBundle\Entity\Post',
458
                'admin_myapplication_my_post',
459
            ],
460
            [
461
                'MyApplication\MyBundle\Entity\Post\Category',
462
                'admin_myapplication_my_post_category',
463
            ],
464
            [
465
                'MyApplication\MyBundle\Entity\Product\Category',
466
                'admin_myapplication_my_product_category',
467
            ],
468
            [
469
                'MyApplication\MyBundle\Entity\Other\Product\Category',
470
                'admin_myapplication_my_other_product_category',
471
            ],
472
            [
473
                'Symfony\Cmf\Bundle\FooBundle\Document\Menu',
474
                'admin_cmf_foo_menu',
475
            ],
476
            [
477
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Phpcr\Menu',
478
                'admin_cmf_foo_menu',
479
            ],
480
            [
481
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu',
482
                'admin_symfony_barbar_menu',
483
            ],
484
            [
485
                'Symfony\Bundle\BarBarBundle\Doctrine\Phpcr\Menu\Item',
486
                'admin_symfony_barbar_menu_item',
487
            ],
488
            [
489
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\Orm\Menu',
490
                'admin_cmf_foo_menu',
491
            ],
492
            [
493
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\MongoDB\Menu',
494
                'admin_cmf_foo_menu',
495
            ],
496
            [
497
                'Symfony\Cmf\Bundle\FooBundle\Doctrine\CouchDB\Menu',
498
                'admin_cmf_foo_menu',
499
            ],
500
            [
501
                'AppBundle\Entity\User',
502
                'admin_app_user',
503
            ],
504
            [
505
                'App\Entity\User',
506
                'admin_app_user',
507
            ],
508
        ];
509
    }
510
511
    /**
512
     * @dataProvider provideGetBaseRouteName
513
     */
514
    public function testGetBaseRouteName(string $objFqn, string $expected): void
515
    {
516
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
517
518
        $this->assertSame($expected, $admin->getBaseRouteName());
519
    }
520
521
    /**
522
     * @group legacy
523
     * @expectedDeprecation Calling "addChild" without second argument is deprecated since sonata-project/admin-bundle 3.35 and will not be allowed in 4.0.
524
     * @dataProvider provideGetBaseRouteName
525
     */
526
    public function testGetBaseRouteNameWithChildAdmin(string $objFqn, string $expected): void
527
    {
528
        $routeGenerator = new DefaultRouteGenerator(
529
            $this->createMock(RouterInterface::class),
530
            new RoutesCache($this->cacheTempFolder, true)
531
        );
532
533
        $container = new Container();
534
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
535
536
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
537
        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
538
        $container->set('sonata.post.admin.post', $postAdmin);
539
        $postAdmin->setConfigurationPool($pool);
540
        $postAdmin->setRouteBuilder($pathInfo);
541
        $postAdmin->setRouteGenerator($routeGenerator);
542
        $postAdmin->initialize();
543
544
        $commentAdmin = new CommentAdmin(
545
            'sonata.post.admin.comment',
546
            'Application\Sonata\NewsBundle\Entity\Comment',
547
            'SonataNewsBundle:CommentAdmin'
548
        );
549
        $container->set('sonata.post.admin.comment', $commentAdmin);
550
        $commentAdmin->setConfigurationPool($pool);
551
        $commentAdmin->setRouteBuilder($pathInfo);
552
        $commentAdmin->setRouteGenerator($routeGenerator);
553
        $commentAdmin->initialize();
554
555
        $postAdmin->addChild($commentAdmin, 'post');
556
557
        $commentVoteAdmin = new CommentVoteAdmin(
558
            'sonata.post.admin.comment_vote',
559
            'Application\Sonata\NewsBundle\Entity\CommentVote',
560
            'SonataNewsBundle:CommentVoteAdmin'
561
        );
562
563
        $container->set('sonata.post.admin.comment_vote', $commentVoteAdmin);
564
        $commentVoteAdmin->setConfigurationPool($pool);
565
        $commentVoteAdmin->setRouteBuilder($pathInfo);
566
        $commentVoteAdmin->setRouteGenerator($routeGenerator);
567
        $commentVoteAdmin->initialize();
568
569
        $commentAdmin->addChild($commentVoteAdmin);
570
        $pool->setAdminServiceIds([
571
            'sonata.post.admin.post',
572
            'sonata.post.admin.comment',
573
            'sonata.post.admin.comment_vote',
574
        ]);
575
576
        $this->assertSame($expected.'_comment', $commentAdmin->getBaseRouteName());
577
578
        $this->assertTrue($postAdmin->hasRoute('show'));
579
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
580
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.show'));
581
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment|sonata.post.admin.comment_vote.show'));
582
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment.list'));
583
        $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.comment|sonata.post.admin.comment_vote.list'));
584
        $this->assertFalse($postAdmin->hasRoute('sonata.post.admin.post|sonata.post.admin.comment.edit'));
585
        $this->assertFalse($commentAdmin->hasRoute('edit'));
586
        $this->assertSame('post', $commentAdmin->getParentAssociationMapping());
587
588
        /*
589
         * Test the route name from request
590
         */
591
        $postListRequest = new Request(
592
            [],
593
            [],
594
            [
595
                '_route' => $postAdmin->getBaseRouteName().'_list',
596
            ]
597
        );
598
599
        $postAdmin->setRequest($postListRequest);
600
        $commentAdmin->setRequest($postListRequest);
601
602
        $this->assertTrue($postAdmin->isCurrentRoute('list'));
603
        $this->assertFalse($postAdmin->isCurrentRoute('create'));
604
        $this->assertFalse($commentAdmin->isCurrentRoute('list'));
605
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('list'));
606
        $this->assertTrue($commentAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
607
        $this->assertFalse($commentAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
608
        $this->assertTrue($commentVoteAdmin->isCurrentRoute('list', 'sonata.post.admin.post'));
609
        $this->assertFalse($commentVoteAdmin->isCurrentRoute('edit', 'sonata.post.admin.post'));
610
    }
611
612
    public function testGetBaseRouteNameWithUnreconizedClassname(): void
613
    {
614
        $this->expectException(\RuntimeException::class);
615
616
        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'SonataNewsBundle:PostAdmin');
617
        $admin->getBaseRouteName();
618
    }
619
620
    public function testGetBaseRouteNameWithSpecifiedName(): void
621
    {
622
        $postAdmin = new PostWithCustomRouteAdmin('sonata.post.admin.post_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
623
624
        $this->assertSame('post_custom', $postAdmin->getBaseRouteName());
625
    }
626
627
    public function testGetBaseRouteNameWithChildAdminAndWithSpecifiedName(): void
628
    {
629
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
630
        $commentAdmin = new CommentWithCustomRouteAdmin('sonata.post.admin.comment_with_custom_route', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentWithCustomRouteAdmin');
631
        $commentAdmin->setParent($postAdmin);
632
633
        $this->assertSame('admin_sonata_news_post_comment_custom', $commentAdmin->getBaseRouteName());
634
    }
635
636
    public function testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName(): void
637
    {
638
        $postAdmin = new PostAdmin(
639
            'sonata.post.admin.post',
640
            'Application\Sonata\NewsBundle\Entity\Post',
641
            'SonataNewsBundle:PostAdmin'
642
        );
643
        $commentAdmin = new CommentWithCustomRouteAdmin(
644
            'sonata.post.admin.comment_with_custom_route',
645
            'Application\Sonata\NewsBundle\Entity\Comment',
646
            'SonataNewsBundle:CommentWithCustomRouteAdmin'
647
        );
648
        $commentVoteAdmin = new CommentVoteAdmin(
649
            'sonata.post.admin.comment_vote',
650
            'Application\Sonata\NewsBundle\Entity\CommentVote',
651
            'SonataNewsBundle:CommentVoteAdmin'
652
        );
653
        $commentAdmin->setParent($postAdmin);
654
        $commentVoteAdmin->setParent($commentAdmin);
655
656
        $this->assertSame('admin_sonata_news_post_comment_custom_commentvote', $commentVoteAdmin->getBaseRouteName());
657
    }
658
659
    /**
660
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setUniqid
661
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getUniqid
662
     */
663
    public function testSetUniqid(): void
664
    {
665
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
666
667
        $uniqid = uniqid();
668
        $admin->setUniqid($uniqid);
669
670
        $this->assertSame($uniqid, $admin->getUniqid());
671
    }
672
673
    public function testToString(): void
674
    {
675
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
676
677
        $s = new \stdClass();
678
679
        $this->assertNotEmpty($admin->toString($s));
680
681
        $s = new FooToString();
682
        $this->assertSame('salut', $admin->toString($s));
683
684
        // To string method is implemented, but returns null
685
        $s = new FooToStringNull();
686
        $this->assertNotEmpty($admin->toString($s));
687
688
        $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...
689
    }
690
691
    public function testIsAclEnabled(): void
692
    {
693
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
694
695
        $this->assertFalse($postAdmin->isAclEnabled());
696
697
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
698
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
699
        $this->assertTrue($commentAdmin->isAclEnabled());
700
    }
701
702
    /**
703
     * @group legacy
704
     *
705
     * @expectedDeprecation Calling Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode() when there is no active subclass is deprecated since sonata-project/admin-bundle 3.52 and will throw an exception in 4.0. Use Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass() to know if there is an active subclass.
706
     *
707
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
708
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
709
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
710
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
711
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
712
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
713
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
714
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
715
     */
716
    public function testSubClass(): void
717
    {
718
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
719
        $admin = new PostAdmin(
720
            'sonata.post.admin.post',
721
            Post::class,
722
            'SonataNewsBundle:PostAdmin'
723
        );
724
        $this->assertFalse($admin->hasSubClass('test'));
725
        $this->assertFalse($admin->hasActiveSubClass());
726
        $this->assertCount(0, $admin->getSubClasses());
727
        $this->assertNull($admin->getActiveSubClass());
728
        $this->assertNull($admin->getActiveSubclassCode());
729
        $this->assertSame(Post::class, $admin->getClass());
730
731
        // Just for the record, if there is no inheritance set, the getSubject is not used
732
        // the getSubject can also lead to some issue
733
        $admin->setSubject(new BlogPost());
734
        $this->assertSame(BlogPost::class, $admin->getClass());
735
736
        $admin->setSubClasses([
737
            'extended1' => 'NewsBundle\Entity\PostExtended1',
738
            'extended2' => 'NewsBundle\Entity\PostExtended2',
739
        ]);
740
        $this->assertFalse($admin->hasSubClass('test'));
741
        $this->assertTrue($admin->hasSubClass('extended1'));
742
        $this->assertFalse($admin->hasActiveSubClass());
743
        $this->assertCount(2, $admin->getSubClasses());
744
        // NEXT_MAJOR: remove the following 2 `assertNull()` assertions
745
        $this->assertNull($admin->getActiveSubClass());
746
        $this->assertNull($admin->getActiveSubclassCode());
747
        $this->assertSame(
748
            BlogPost::class,
749
            $admin->getClass(),
750
            'When there is no subclass in the query the class parameter should be returned'
751
        );
752
753
        $request = new Request(['subclass' => 'extended1']);
754
        $admin->setRequest($request);
755
        $this->assertFalse($admin->hasSubClass('test'));
756
        $this->assertTrue($admin->hasSubClass('extended1'));
757
        $this->assertTrue($admin->hasActiveSubClass());
758
        $this->assertCount(2, $admin->getSubClasses());
759
        $this->assertSame(
760
            'NewsBundle\Entity\PostExtended1',
761
            $admin->getActiveSubClass(),
762
            'It should return the curently active sub class.'
763
        );
764
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
765
        $this->assertSame(
766
            'NewsBundle\Entity\PostExtended1',
767
            $admin->getClass(),
768
            'getClass() should return the name of the sub class when passed through a request query parameter.'
769
        );
770
771
        $request->query->set('subclass', 'inject');
772
773
        $this->assertNull($admin->getActiveSubclassCode());
774
        // NEXT_MAJOR: remove the previous `assertNull()` assertion and uncomment the following lines
775
        // $this->expectException(\LogicException::class);
776
        // $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
777
    }
778
779
    /**
780
     * @group legacy
781
     *
782
     * @expectedDeprecation Calling Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode() when there is no active subclass is deprecated since sonata-project/admin-bundle 3.52 and will throw an exception in 4.0. Use Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass() to know if there is an active subclass.
783
     */
784
    public function testNonExistantSubclass(): void
785
    {
786
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
787
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
788
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
789
790
        $admin->setRequest(new Request(['subclass' => 'inject']));
791
792
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
793
794
        $this->assertTrue($admin->hasActiveSubClass());
795
796
        $this->expectException(\RuntimeException::class);
797
798
        $admin->getActiveSubClass();
799
    }
800
801
    /**
802
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
803
     */
804
    public function testOnlyOneSubclassNeededToBeActive(): void
805
    {
806
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
807
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
808
        $request = new Request(['subclass' => 'extended1']);
809
        $admin->setRequest($request);
810
        $this->assertTrue($admin->hasActiveSubClass());
811
    }
812
813
    /**
814
     * @group legacy
815
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since sonata-project/admin-bundle 3.30 and will be removed in 4.0.
816
     */
817
    public function testAddSubClassIsDeprecated(): void
818
    {
819
        $admin = new PostAdmin(
820
            'sonata.post.admin.post',
821
            Post::class,
822
            'SonataNewsBundle:PostAdmin'
823
        );
824
        $admin->addSubClass('whatever');
825
    }
826
827
    public function testGetPerPageOptions(): void
828
    {
829
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
830
831
        $perPageOptions = $admin->getPerPageOptions();
832
833
        foreach ($perPageOptions as $perPage) {
834
            $this->assertSame(0, $perPage % 4);
835
        }
836
837
        $admin->setPerPageOptions([500, 1000]);
838
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
839
    }
840
841
    public function testGetLabelTranslatorStrategy(): void
842
    {
843
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
844
845
        $this->assertNull($admin->getLabelTranslatorStrategy());
846
847
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
848
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
849
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
850
    }
851
852
    public function testGetRouteBuilder(): void
853
    {
854
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
855
856
        $this->assertNull($admin->getRouteBuilder());
857
858
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
859
        $admin->setRouteBuilder($routeBuilder);
860
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
861
    }
862
863
    public function testGetMenuFactory(): void
864
    {
865
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
866
867
        $this->assertNull($admin->getMenuFactory());
868
869
        $menuFactory = $this->createMock(FactoryInterface::class);
870
        $admin->setMenuFactory($menuFactory);
871
        $this->assertSame($menuFactory, $admin->getMenuFactory());
872
    }
873
874
    public function testGetExtensions(): void
875
    {
876
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
877
878
        $this->assertSame([], $admin->getExtensions());
879
880
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
881
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
882
883
        $admin->addExtension($adminExtension1);
884
        $admin->addExtension($adminExtension2);
885
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
886
    }
887
888
    public function testGetFilterTheme(): void
889
    {
890
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
891
892
        $this->assertSame([], $admin->getFilterTheme());
893
894
        $admin->setFilterTheme(['FooTheme']);
895
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
896
    }
897
898
    public function testGetFormTheme(): void
899
    {
900
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
901
902
        $this->assertSame([], $admin->getFormTheme());
903
904
        $admin->setFormTheme(['FooTheme']);
905
906
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
907
    }
908
909
    public function testGetValidator(): void
910
    {
911
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
912
913
        $this->assertNull($admin->getValidator());
914
915
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
916
917
        $admin->setValidator($validator);
918
        $this->assertSame($validator, $admin->getValidator());
919
    }
920
921
    public function testGetSecurityHandler(): void
922
    {
923
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
924
925
        $this->assertNull($admin->getSecurityHandler());
926
927
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
928
        $admin->setSecurityHandler($securityHandler);
929
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
930
    }
931
932
    public function testGetSecurityInformation(): void
933
    {
934
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
935
936
        $this->assertSame([], $admin->getSecurityInformation());
937
938
        $securityInformation = [
939
            'GUEST' => ['VIEW', 'LIST'],
940
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
941
        ];
942
943
        $admin->setSecurityInformation($securityInformation);
944
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
945
    }
946
947
    public function testGetManagerType(): void
948
    {
949
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
950
951
        $this->assertNull($admin->getManagerType());
952
953
        $admin->setManagerType('foo_orm');
954
        $this->assertSame('foo_orm', $admin->getManagerType());
955
    }
956
957
    public function testGetModelManager(): void
958
    {
959
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
960
961
        $this->assertNull($admin->getModelManager());
962
963
        $modelManager = $this->createMock(ModelManagerInterface::class);
964
965
        $admin->setModelManager($modelManager);
966
        $this->assertSame($modelManager, $admin->getModelManager());
967
    }
968
969
    /**
970
     * NEXT_MAJOR: remove this method.
971
     *
972
     * @group legacy
973
     */
974
    public function testGetBaseCodeRoute(): void
975
    {
976
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
977
978
        $this->assertSame('', $admin->getBaseCodeRoute());
979
980
        $admin->setBaseCodeRoute('foo');
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...min::setBaseCodeRoute() has been deprecated with message: This method is deprecated since sonata-project/admin-bundle 3.24 and will 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...
981
        $this->assertSame('foo', $admin->getBaseCodeRoute());
982
    }
983
984
    // NEXT_MAJOR: uncomment this method.
985
    // public function testGetBaseCodeRoute()
986
    // {
987
    //     $postAdmin = new PostAdmin(
988
    //         'sonata.post.admin.post',
989
    //         'NewsBundle\Entity\Post',
990
    //         'SonataNewsBundle:PostAdmin'
991
    //     );
992
    //     $commentAdmin = new CommentAdmin(
993
    //         'sonata.post.admin.comment',
994
    //         'Application\Sonata\NewsBundle\Entity\Comment',
995
    //         'SonataNewsBundle:CommentAdmin'
996
    //     );
997
    //
998
    //     $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
999
    //
1000
    //     $postAdmin->addChild($commentAdmin);
1001
    //
1002
    //     $this->assertSame(
1003
    //         'sonata.post.admin.post|sonata.post.admin.comment',
1004
    //         $commentAdmin->getBaseCodeRoute()
1005
    //     );
1006
    // }
1007
1008
    public function testGetRouteGenerator(): void
1009
    {
1010
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1011
1012
        $this->assertNull($admin->getRouteGenerator());
1013
1014
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1015
1016
        $admin->setRouteGenerator($routeGenerator);
1017
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1018
    }
1019
1020
    public function testGetConfigurationPool(): void
1021
    {
1022
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1023
1024
        $this->assertNull($admin->getConfigurationPool());
1025
1026
        $pool = $this->getMockBuilder(Pool::class)
1027
            ->disableOriginalConstructor()
1028
            ->getMock();
1029
1030
        $admin->setConfigurationPool($pool);
1031
        $this->assertSame($pool, $admin->getConfigurationPool());
1032
    }
1033
1034
    public function testGetShowBuilder(): void
1035
    {
1036
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1037
1038
        $this->assertNull($admin->getShowBuilder());
1039
1040
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1041
1042
        $admin->setShowBuilder($showBuilder);
1043
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1044
    }
1045
1046
    public function testGetListBuilder(): void
1047
    {
1048
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1049
1050
        $this->assertNull($admin->getListBuilder());
1051
1052
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1053
1054
        $admin->setListBuilder($listBuilder);
1055
        $this->assertSame($listBuilder, $admin->getListBuilder());
1056
    }
1057
1058
    public function testGetDatagridBuilder(): void
1059
    {
1060
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1061
1062
        $this->assertNull($admin->getDatagridBuilder());
1063
1064
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1065
1066
        $admin->setDatagridBuilder($datagridBuilder);
1067
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1068
    }
1069
1070
    public function testGetFormContractor(): void
1071
    {
1072
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1073
1074
        $this->assertNull($admin->getFormContractor());
1075
1076
        $formContractor = $this->createMock(FormContractorInterface::class);
1077
1078
        $admin->setFormContractor($formContractor);
1079
        $this->assertSame($formContractor, $admin->getFormContractor());
1080
    }
1081
1082
    public function testGetRequest(): void
1083
    {
1084
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1085
1086
        $this->assertFalse($admin->hasRequest());
1087
1088
        $request = new Request();
1089
1090
        $admin->setRequest($request);
1091
        $this->assertSame($request, $admin->getRequest());
1092
        $this->assertTrue($admin->hasRequest());
1093
    }
1094
1095
    public function testGetRequestWithException(): void
1096
    {
1097
        $this->expectException(\RuntimeException::class);
1098
        $this->expectExceptionMessage('The Request object has not been set');
1099
1100
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1101
        $admin->getRequest();
1102
    }
1103
1104
    public function testGetTranslationDomain(): void
1105
    {
1106
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1107
1108
        $this->assertSame('messages', $admin->getTranslationDomain());
1109
1110
        $admin->setTranslationDomain('foo');
1111
        $this->assertSame('foo', $admin->getTranslationDomain());
1112
    }
1113
1114
    /**
1115
     * @group legacy
1116
     */
1117
    public function testGetTranslator(): void
1118
    {
1119
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1120
1121
        $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...
1122
1123
        $translator = $this->createMock(TranslatorInterface::class);
1124
1125
        $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...
1126
        $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...
1127
    }
1128
1129
    public function testGetShowGroups(): void
1130
    {
1131
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1132
1133
        $this->assertFalse($admin->getShowGroups());
1134
1135
        $groups = ['foo', 'bar', 'baz'];
1136
1137
        $admin->setShowGroups($groups);
1138
        $this->assertSame($groups, $admin->getShowGroups());
1139
    }
1140
1141
    public function testGetFormGroups(): void
1142
    {
1143
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1144
1145
        $this->assertFalse($admin->getFormGroups());
1146
1147
        $groups = ['foo', 'bar', 'baz'];
1148
1149
        $admin->setFormGroups($groups);
1150
        $this->assertSame($groups, $admin->getFormGroups());
1151
    }
1152
1153
    public function testGetMaxPageLinks(): void
1154
    {
1155
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1156
1157
        $this->assertSame(25, $admin->getMaxPageLinks());
1158
1159
        $admin->setMaxPageLinks(14);
1160
        $this->assertSame(14, $admin->getMaxPageLinks());
1161
    }
1162
1163
    public function testGetMaxPerPage(): void
1164
    {
1165
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1166
1167
        $this->assertSame(32, $admin->getMaxPerPage());
1168
1169
        $admin->setMaxPerPage(94);
1170
        $this->assertSame(94, $admin->getMaxPerPage());
1171
    }
1172
1173
    public function testGetLabel(): void
1174
    {
1175
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1176
1177
        $this->assertNull($admin->getLabel());
1178
1179
        $admin->setLabel('FooLabel');
1180
        $this->assertSame('FooLabel', $admin->getLabel());
1181
    }
1182
1183
    public function testGetBaseController(): void
1184
    {
1185
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1186
1187
        $this->assertSame('SonataNewsBundle:PostAdmin', $admin->getBaseControllerName());
1188
1189
        $admin->setBaseControllerName('SonataNewsBundle:FooAdmin');
1190
        $this->assertSame('SonataNewsBundle:FooAdmin', $admin->getBaseControllerName());
1191
    }
1192
1193
    public function testGetTemplates(): void
1194
    {
1195
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1196
1197
        $templates = [
1198
            'list' => '@FooAdmin/CRUD/list.html.twig',
1199
            'show' => '@FooAdmin/CRUD/show.html.twig',
1200
            'edit' => '@FooAdmin/CRUD/edit.html.twig',
1201
        ];
1202
1203
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1204
        $templateRegistry->getTemplates()->shouldBeCalled()->willReturn($templates);
1205
1206
        $admin->setTemplateRegistry($templateRegistry->reveal());
1207
1208
        $this->assertSame($templates, $admin->getTemplates());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...ctAdmin::getTemplates() has been deprecated with message: since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead

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...
1209
    }
1210
1211
    public function testGetTemplate1(): void
1212
    {
1213
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1214
1215
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1216
        $templateRegistry->getTemplate('edit')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/edit.html.twig');
1217
        $templateRegistry->getTemplate('show')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/show.html.twig');
1218
1219
        $admin->setTemplateRegistry($templateRegistry->reveal());
1220
1221
        $this->assertSame('@FooAdmin/CRUD/edit.html.twig', $admin->getTemplate('edit'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::getTemplate() has been deprecated with message: since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead

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...
1222
        $this->assertSame('@FooAdmin/CRUD/show.html.twig', $admin->getTemplate('show'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...actAdmin::getTemplate() has been deprecated with message: since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead

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...
1223
    }
1224
1225
    public function testGetIdParameter(): void
1226
    {
1227
        $postAdmin = new PostAdmin(
1228
            'sonata.post.admin.post',
1229
            'NewsBundle\Entity\Post',
1230
            'SonataNewsBundle:PostAdmin'
1231
        );
1232
1233
        $this->assertSame('id', $postAdmin->getIdParameter());
1234
        $this->assertFalse($postAdmin->isChild());
1235
1236
        $commentAdmin = new CommentAdmin(
1237
            'sonata.post.admin.comment',
1238
            'Application\Sonata\NewsBundle\Entity\Comment',
1239
            'SonataNewsBundle:CommentAdmin'
1240
        );
1241
        $commentAdmin->setParent($postAdmin);
1242
1243
        $this->assertTrue($commentAdmin->isChild());
1244
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1245
1246
        $commentVoteAdmin = new CommentVoteAdmin(
1247
            'sonata.post.admin.comment_vote',
1248
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1249
            'SonataNewsBundle:CommentVoteAdmin'
1250
        );
1251
        $commentVoteAdmin->setParent($commentAdmin);
1252
1253
        $this->assertTrue($commentVoteAdmin->isChild());
1254
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1255
    }
1256
1257
    public function testGetExportFormats(): void
1258
    {
1259
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1260
1261
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1262
    }
1263
1264
    public function testGetUrlsafeIdentifier(): void
1265
    {
1266
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1267
1268
        $entity = new \stdClass();
1269
1270
        $modelManager = $this->createMock(ModelManagerInterface::class);
1271
        $modelManager->expects($this->once())
1272
            ->method('getUrlsafeIdentifier')
1273
            ->with($this->equalTo($entity))
1274
            ->willReturn('foo');
1275
        $admin->setModelManager($modelManager);
1276
1277
        $this->assertSame('foo', $admin->getUrlsafeIdentifier($entity));
1278
    }
1279
1280
    public function testDeterminedPerPageValue(): void
1281
    {
1282
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1283
1284
        $this->assertFalse($admin->determinedPerPageValue('foo'));
1285
        $this->assertFalse($admin->determinedPerPageValue(123));
1286
        $this->assertTrue($admin->determinedPerPageValue(16));
1287
1288
        $admin->setPerPageOptions([101, 102, 103]);
1289
        $this->assertFalse($admin->determinedPerPageValue(16));
1290
        $this->assertTrue($admin->determinedPerPageValue(101));
1291
    }
1292
1293
    public function testIsGranted(): void
1294
    {
1295
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1296
1297
        $entity = new \stdClass();
1298
1299
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1300
        $securityHandler
1301
            ->method('isGranted')
1302
            ->willReturnCallback(static function (
1303
                AdminInterface $adminIn,
1304
                string $attributes,
1305
                $object = null
1306
            ) use (
1307
                $admin,
1308
                $entity
1309
            ): bool {
1310
                if ($admin === $adminIn && 'FOO' === $attributes) {
1311
                    if (($object === $admin) || ($object === $entity)) {
1312
                        return true;
1313
                    }
1314
                }
1315
1316
                return false;
1317
            });
1318
1319
        $admin->setSecurityHandler($securityHandler);
1320
1321
        $this->assertTrue($admin->isGranted('FOO'));
1322
        $this->assertTrue($admin->isGranted('FOO', $entity));
1323
        $this->assertFalse($admin->isGranted('BAR'));
1324
        $this->assertFalse($admin->isGranted('BAR', $entity));
1325
    }
1326
1327
    public function testSupportsPreviewMode(): void
1328
    {
1329
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1330
1331
        $this->assertFalse($admin->supportsPreviewMode());
1332
    }
1333
1334
    public function testGetPermissionsShow(): void
1335
    {
1336
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1337
1338
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1339
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1340
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1341
    }
1342
1343
    public function testShowIn(): void
1344
    {
1345
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1346
1347
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1348
        $securityHandler
1349
            ->method('isGranted')
1350
            ->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...
1351
                return $admin === $adminIn && $attributes === ['LIST'];
1352
            });
1353
1354
        $admin->setSecurityHandler($securityHandler);
1355
1356
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1357
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1358
        $this->assertTrue($admin->showIn('foo'));
1359
    }
1360
1361
    public function testGetObjectIdentifier(): void
1362
    {
1363
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1364
1365
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1366
    }
1367
1368
    /**
1369
     * @group legacy
1370
     */
1371
    public function testTrans(): void
1372
    {
1373
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1374
        $admin->setTranslationDomain('fooMessageDomain');
1375
1376
        $translator = $this->createMock(TranslatorInterface::class);
1377
        $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...
1378
1379
        $translator->expects($this->once())
1380
            ->method('trans')
1381
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1382
            ->willReturn('fooTranslated');
1383
1384
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1385
    }
1386
1387
    /**
1388
     * @group legacy
1389
     */
1390
    public function testTransWithMessageDomain(): void
1391
    {
1392
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1393
1394
        $translator = $this->createMock(TranslatorInterface::class);
1395
        $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...
1396
1397
        $translator->expects($this->once())
1398
            ->method('trans')
1399
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1400
            ->willReturn('fooTranslated');
1401
1402
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1403
    }
1404
1405
    /**
1406
     * @group legacy
1407
     */
1408
    public function testTransChoice(): void
1409
    {
1410
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1411
        $admin->setTranslationDomain('fooMessageDomain');
1412
1413
        $translator = $this->createMock(TranslatorInterface::class);
1414
        $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...
1415
1416
        $translator->expects($this->once())
1417
            ->method('transChoice')
1418
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1419
            ->willReturn('fooTranslated');
1420
1421
        $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...
1422
    }
1423
1424
    /**
1425
     * @group legacy
1426
     */
1427
    public function testTransChoiceWithMessageDomain(): void
1428
    {
1429
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1430
1431
        $translator = $this->createMock(TranslatorInterface::class);
1432
        $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...
1433
1434
        $translator->expects($this->once())
1435
            ->method('transChoice')
1436
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1437
            ->willReturn('fooTranslated');
1438
1439
        $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...
1440
    }
1441
1442
    public function testSetFilterPersister(): void
1443
    {
1444
        $admin = new class('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController') extends PostAdmin {
1445
            public function persistFilters(): bool
1446
            {
1447
                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...
1448
            }
1449
        };
1450
1451
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1452
1453
        $admin->setFilterPersister($filterPersister);
1454
        $this->assertTrue($admin->persistFilters());
1455
    }
1456
1457
    public function testGetRootCode(): void
1458
    {
1459
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1460
1461
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1462
1463
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'SonataNewsBundle:PostParentAdmin');
1464
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1465
        $parentFieldDescription->expects($this->once())
1466
            ->method('getAdmin')
1467
            ->willReturn($parentAdmin);
1468
1469
        $this->assertNull($admin->getParentFieldDescription());
1470
        $admin->setParentFieldDescription($parentFieldDescription);
1471
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1472
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1473
    }
1474
1475
    public function testGetRoot(): void
1476
    {
1477
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1478
1479
        $this->assertSame($admin, $admin->getRoot());
1480
1481
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'SonataNewsBundle:PostParentAdmin');
1482
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1483
        $parentFieldDescription->expects($this->once())
1484
            ->method('getAdmin')
1485
            ->willReturn($parentAdmin);
1486
1487
        $this->assertNull($admin->getParentFieldDescription());
1488
        $admin->setParentFieldDescription($parentFieldDescription);
1489
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1490
        $this->assertSame($parentAdmin, $admin->getRoot());
1491
    }
1492
1493
    public function testGetExportFields(): void
1494
    {
1495
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1496
1497
        $modelManager = $this->createMock(ModelManagerInterface::class);
1498
        $modelManager->expects($this->once())
1499
            ->method('getExportFields')
1500
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1501
            ->willReturn(['foo', 'bar']);
1502
1503
        $admin->setModelManager($modelManager);
1504
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1505
    }
1506
1507
    public function testGetPersistentParametersWithNoExtension(): void
1508
    {
1509
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1510
1511
        $this->assertEmpty($admin->getPersistentParameters());
1512
    }
1513
1514
    public function testGetPersistentParametersWithInvalidExtension(): void
1515
    {
1516
        $this->expectException(\RuntimeException::class);
1517
1518
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1519
1520
        $extension = $this->createMock(AdminExtensionInterface::class);
1521
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn(null);
1522
1523
        $admin->addExtension($extension);
1524
1525
        $admin->getPersistentParameters();
1526
    }
1527
1528
    public function testGetPersistentParametersWithValidExtension(): void
1529
    {
1530
        $expected = [
1531
            'context' => 'foobar',
1532
        ];
1533
1534
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1535
1536
        $extension = $this->createMock(AdminExtensionInterface::class);
1537
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1538
1539
        $admin->addExtension($extension);
1540
1541
        $this->assertSame($expected, $admin->getPersistentParameters());
1542
    }
1543
1544
    public function testGetFormWithNonCollectionParentValue(): void
1545
    {
1546
        $post = new Post();
1547
        $tagAdmin = $this->createTagAdmin($post);
1548
        $tag = $tagAdmin->getSubject();
1549
1550
        $tag->setPosts(null);
1551
        $tagAdmin->getForm();
1552
        $this->assertSame($post, $tag->getPosts());
1553
    }
1554
1555
    public function testGetFormWithCollectionParentValue(): void
1556
    {
1557
        $post = new Post();
1558
        $tagAdmin = $this->createTagAdmin($post);
1559
        $tag = $tagAdmin->getSubject();
1560
1561
        // Case of a doctrine collection
1562
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1563
        $this->assertCount(0, $tag->getPosts());
1564
1565
        $tag->addPost(new Post());
1566
1567
        $this->assertCount(1, $tag->getPosts());
1568
1569
        $tagAdmin->getForm();
1570
1571
        $this->assertInstanceOf(Collection::class, $tag->getPosts());
1572
        $this->assertCount(2, $tag->getPosts());
1573
        $this->assertContains($post, $tag->getPosts());
1574
1575
        // Case of an array
1576
        $tag->setPosts([]);
1577
        $this->assertCount(0, $tag->getPosts());
1578
1579
        $tag->addPost(new Post());
1580
1581
        $this->assertCount(1, $tag->getPosts());
1582
1583
        $tagAdmin->getForm();
1584
1585
        $this->assertIsArray($tag->getPosts());
1586
        $this->assertCount(2, $tag->getPosts());
1587
        $this->assertContains($post, $tag->getPosts());
1588
    }
1589
1590
    public function testFormAddPostSubmitEventForPreValidation(): void
1591
    {
1592
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
1593
        $object = new \stdClass();
1594
1595
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1596
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1597
1598
        $validator = $this->createMock(ValidatorInterface::class);
1599
        $validator
1600
                ->method('getMetadataFor')
1601
                ->willReturn($this->createMock(MemberMetadata::class));
1602
        $modelAdmin->setValidator($validator);
1603
1604
        $modelManager = $this->createMock(ModelManagerInterface::class);
1605
        $modelManager
1606
            ->method('getNewFieldDescriptionInstance')
1607
            ->willReturn(new FieldDescription());
1608
        $modelAdmin->setModelManager($modelManager);
1609
1610
        // a Admin class to test that preValidate is called
1611
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1612
        $testAdminPreValidate->expects($this->once())
1613
                ->method('preValidate')
1614
                ->with($this->identicalTo($object));
1615
1616
        $event = $this->createMock(FormEvent::class);
1617
        $event
1618
                ->method('getData')
1619
                ->willReturn($object);
1620
1621
        $formBuild = $this->createMock(FormBuilder::class);
1622
        $formBuild->expects($this->once())
1623
                ->method('addEventListener')
1624
                ->with(
1625
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1626
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1627
                        if (\is_callable($callback)) {
1628
                            $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...
1629
                            $closure($event);
1630
1631
                            return true;
1632
                        }
1633
1634
                        return false;
1635
                    }),
1636
                    $this->greaterThan(0)
1637
                );
1638
1639
        $formContractor = $this->createMock(FormContractorInterface::class);
1640
        $formContractor
1641
                ->method('getDefaultOptions')
1642
                ->willReturn([]);
1643
        $formContractor
1644
                ->method('getFormBuilder')
1645
                ->willReturn($formBuild);
1646
1647
        $modelAdmin->setFormContractor($formContractor);
1648
        $modelAdmin->defineFormBuilder($formBuild);
1649
        $modelAdmin->getForm();
1650
    }
1651
1652
    public function testRemoveFieldFromFormGroup(): void
1653
    {
1654
        $formGroups = [
1655
            'foobar' => [
1656
                'fields' => [
1657
                    'foo' => 'foo',
1658
                    'bar' => 'bar',
1659
                ],
1660
            ],
1661
        ];
1662
1663
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1664
        $admin->setFormGroups($formGroups);
1665
1666
        $admin->removeFieldFromFormGroup('foo');
1667
        $this->assertSame($admin->getFormGroups(), [
1668
            'foobar' => [
1669
                'fields' => [
1670
                    'bar' => 'bar',
1671
                ],
1672
            ],
1673
        ]);
1674
1675
        $admin->removeFieldFromFormGroup('bar');
1676
        $this->assertSame($admin->getFormGroups(), []);
1677
    }
1678
1679
    public function testGetFilterParameters(): void
1680
    {
1681
        $authorId = uniqid();
1682
1683
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1684
1685
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
1686
        $commentAdmin->setParentAssociationMapping('post.author');
1687
        $commentAdmin->setParent($postAdmin);
1688
1689
        $request = $this->createMock(Request::class);
1690
        $query = $this->createMock(ParameterBag::class);
1691
        $query
1692
            ->method('get')
1693
            ->willReturn([
1694
                'filter' => [
1695
                    '_page' => '1',
1696
                    '_per_page' => '32',
1697
                ],
1698
            ]);
1699
1700
        $request->query = $query;
1701
        $request
1702
            ->method('get')
1703
            ->willReturn($authorId);
1704
1705
        $commentAdmin->setRequest($request);
1706
1707
        $modelManager = $this->createMock(ModelManagerInterface::class);
1708
        $modelManager
1709
            ->method('getDefaultSortValues')
1710
            ->willReturn([]);
1711
1712
        $commentAdmin->setModelManager($modelManager);
1713
1714
        $parameters = $commentAdmin->getFilterParameters();
1715
1716
        $this->assertTrue(isset($parameters['post__author']));
1717
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1718
    }
1719
1720
    public function testGetFilterFieldDescription(): void
1721
    {
1722
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
1723
1724
        $fooFieldDescription = new FieldDescription();
1725
        $barFieldDescription = new FieldDescription();
1726
        $bazFieldDescription = new FieldDescription();
1727
1728
        $modelManager = $this->createMock(ModelManagerInterface::class);
1729
        $modelManager->expects($this->exactly(3))
1730
            ->method('getNewFieldDescriptionInstance')
1731
            ->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...
1732
                switch ($name) {
1733
                    case 'foo':
1734
                        $fieldDescription = $fooFieldDescription;
1735
1736
                        break;
1737
1738
                    case 'bar':
1739
                        $fieldDescription = $barFieldDescription;
1740
1741
                        break;
1742
1743
                    case 'baz':
1744
                        $fieldDescription = $bazFieldDescription;
1745
1746
                        break;
1747
1748
                    default:
1749
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1750
                        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...
1751
                }
1752
1753
                $fieldDescription->setName($name);
1754
1755
                return $fieldDescription;
1756
            });
1757
1758
        $modelAdmin->setModelManager($modelManager);
1759
1760
        $pager = $this->createMock(PagerInterface::class);
1761
1762
        $datagrid = $this->createMock(DatagridInterface::class);
1763
        $datagrid->expects($this->once())
1764
            ->method('getPager')
1765
            ->willReturn($pager);
1766
1767
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1768
        $datagridBuilder->expects($this->once())
1769
            ->method('getBaseDatagrid')
1770
            ->with($this->identicalTo($modelAdmin), [])
1771
            ->willReturn($datagrid);
1772
1773
        $datagridBuilder->expects($this->exactly(3))
1774
            ->method('addFilter')
1775
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1776
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1777
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1778
            });
1779
1780
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1781
1782
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1783
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1784
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1785
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1786
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1787
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1788
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1789
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1790
    }
1791
1792
    public function testGetSubjectNoRequest(): void
1793
    {
1794
        $modelManager = $this->createMock(ModelManagerInterface::class);
1795
        $modelManager
1796
            ->expects($this->never())
1797
            ->method('find');
1798
1799
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1800
        $admin->setModelManager($modelManager);
1801
1802
        $this->assertNull($admin->getSubject());
1803
    }
1804
1805
    public function testGetSideMenu(): void
1806
    {
1807
        $item = $this->createMock(ItemInterface::class);
1808
        $item
1809
            ->expects($this->once())
1810
            ->method('setChildrenAttribute')
1811
            ->with('class', 'nav navbar-nav');
1812
        $item
1813
            ->expects($this->once())
1814
            ->method('setExtra')
1815
            ->with('translation_domain', 'foo_bar_baz');
1816
1817
        $menuFactory = $this->createMock(FactoryInterface::class);
1818
        $menuFactory
1819
            ->expects($this->once())
1820
            ->method('createItem')
1821
            ->willReturn($item);
1822
1823
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
1824
        $modelAdmin->setMenuFactory($menuFactory);
1825
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1826
1827
        $modelAdmin->getSideMenu('foo');
1828
    }
1829
1830
    /**
1831
     * @return array
1832
     */
1833
    public function provideGetSubject()
1834
    {
1835
        return [
1836
            [23],
1837
            ['azerty'],
1838
            ['4f69bbb5f14a13347f000092'],
1839
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
1840
            ['123'.AdapterInterface::ID_SEPARATOR.'my_type'], // composite keys are supported
1841
        ];
1842
    }
1843
1844
    /**
1845
     * @dataProvider provideGetSubject
1846
     */
1847
    public function testGetSubjectFailed($id): void
1848
    {
1849
        $modelManager = $this->createMock(ModelManagerInterface::class);
1850
        $modelManager
1851
            ->expects($this->once())
1852
            ->method('find')
1853
            ->with('NewsBundle\Entity\Post', $id)
1854
            ->willReturn(null); // entity not found
1855
1856
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1857
        $admin->setModelManager($modelManager);
1858
1859
        $admin->setRequest(new Request(['id' => $id]));
1860
        $this->assertNull($admin->getSubject());
1861
    }
1862
1863
    /**
1864
     * @dataProvider provideGetSubject
1865
     */
1866
    public function testGetSubject($id): void
1867
    {
1868
        $entity = new Post();
1869
1870
        $modelManager = $this->createMock(ModelManagerInterface::class);
1871
        $modelManager
1872
            ->expects($this->once())
1873
            ->method('find')
1874
            ->with('NewsBundle\Entity\Post', $id)
1875
            ->willReturn($entity);
1876
1877
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1878
        $admin->setModelManager($modelManager);
1879
1880
        $admin->setRequest(new Request(['id' => $id]));
1881
        $this->assertSame($entity, $admin->getSubject());
1882
        $this->assertSame($entity, $admin->getSubject()); // model manager must be used only once
1883
    }
1884
1885
    public function testGetSubjectWithParentDescription(): void
1886
    {
1887
        $adminId = 1;
1888
1889
        $comment = new Comment();
1890
1891
        $modelManager = $this->createMock(ModelManagerInterface::class);
1892
        $modelManager
1893
            ->method('find')
1894
            ->with('NewsBundle\Entity\Comment', $adminId)
1895
            ->willReturn($comment);
1896
1897
        $request = new Request(['id' => $adminId]);
1898
1899
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1900
        $postAdmin->setRequest($request);
1901
1902
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
1903
        $commentAdmin->setRequest($request);
1904
        $commentAdmin->setModelManager($modelManager);
1905
1906
        $this->assertSame($comment, $commentAdmin->getSubject());
1907
1908
        $commentAdmin->setSubject(null);
1909
        $commentAdmin->setParentFieldDescription(new FieldDescription());
1910
1911
        $this->assertNull($commentAdmin->getSubject());
1912
    }
1913
1914
    /**
1915
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1916
     */
1917
    public function testGetActionButtonsList(): void
1918
    {
1919
        $expected = [
1920
            'create' => [
1921
                'template' => 'Foo.html.twig',
1922
            ],
1923
        ];
1924
1925
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1926
1927
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1928
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
1929
1930
        $admin->setTemplateRegistry($templateRegistry->reveal());
1931
1932
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1933
        $securityHandler
1934
            ->expects($this->once())
1935
            ->method('isGranted')
1936
            ->with($admin, 'CREATE', $admin)
1937
            ->willReturn(true);
1938
        $admin->setSecurityHandler($securityHandler);
1939
1940
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1941
        $routeGenerator
1942
            ->expects($this->once())
1943
            ->method('hasAdminRoute')
1944
            ->with($admin, 'create')
1945
            ->willReturn(true);
1946
        $admin->setRouteGenerator($routeGenerator);
1947
1948
        $this->assertSame($expected, $admin->getActionButtons('list', null));
1949
    }
1950
1951
    /**
1952
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
1953
     */
1954
    public function testGetActionButtonsListCreateDisabled(): void
1955
    {
1956
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
1957
1958
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
1959
        $securityHandler
1960
            ->expects($this->once())
1961
            ->method('isGranted')
1962
            ->with($admin, 'CREATE', $admin)
1963
            ->willReturn(false);
1964
        $admin->setSecurityHandler($securityHandler);
1965
1966
        $this->assertSame([], $admin->getActionButtons('list', null));
1967
    }
1968
1969
    /**
1970
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
1971
     */
1972
    public function testGetBatchActions(): void
1973
    {
1974
        $expected = [
1975
            'delete' => [
1976
                'label' => 'action_delete',
1977
                'translation_domain' => 'SonataAdminBundle',
1978
                'ask_confirmation' => true, // by default always true
1979
            ],
1980
            'foo' => [
1981
                'label' => 'action_foo',
1982
                'translation_domain' => 'SonataAdminBundle',
1983
            ],
1984
            'bar' => [
1985
                'label' => 'batch.label_bar',
1986
                'translation_domain' => 'SonataAdminBundle',
1987
            ],
1988
            'baz' => [
1989
                'label' => 'action_baz',
1990
                'translation_domain' => 'AcmeAdminBundle',
1991
            ],
1992
        ];
1993
1994
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
1995
1996
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1997
        $labelTranslatorStrategy
1998
            ->method('getLabel')
1999
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2000
                return $context.'.'.$type.'_'.$label;
2001
            });
2002
2003
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
2004
        $admin->setRouteBuilder($pathInfo);
2005
        $admin->setTranslationDomain('SonataAdminBundle');
2006
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
2007
2008
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2009
        $routeGenerator
2010
            ->expects($this->once())
2011
            ->method('hasAdminRoute')
2012
            ->with($admin, 'delete')
2013
            ->willReturn(true);
2014
        $admin->setRouteGenerator($routeGenerator);
2015
2016
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2017
        $securityHandler
2018
            ->method('isGranted')
2019
            ->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...
2020
                return $admin === $adminIn && 'DELETE' === $attributes;
2021
            });
2022
        $admin->setSecurityHandler($securityHandler);
2023
2024
        $this->assertSame($expected, $admin->getBatchActions());
2025
    }
2026
2027
    /**
2028
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2029
     */
2030
    public function testShowMosaicButton(): void
2031
    {
2032
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
2033
        $listModes = $admin->getListModes();
2034
2035
        $admin->showMosaicButton(true);
2036
2037
        $this->assertSame($listModes, $admin->getListModes());
2038
    }
2039
2040
    /**
2041
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2042
     */
2043
    public function testShowMosaicButtonHideMosaic(): void
2044
    {
2045
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
2046
        $listModes = $admin->getListModes();
2047
        $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...
2048
2049
        $admin->showMosaicButton(false);
2050
2051
        $this->assertSame($expected, $admin->getListModes());
2052
    }
2053
2054
    /**
2055
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2056
     * @dataProvider provideGetBaseRouteName
2057
     */
2058
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2059
    {
2060
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2061
2062
        $routeGenerator = new DefaultRouteGenerator(
2063
            $this->createMock(RouterInterface::class),
2064
            new RoutesCache($this->cacheTempFolder, true)
2065
        );
2066
2067
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
2068
        $admin->setRouteBuilder($pathInfo);
2069
        $admin->setRouteGenerator($routeGenerator);
2070
        $admin->initialize();
2071
2072
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2073
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2074
2075
        $admin->setTemplateRegistry($templateRegistry->reveal());
2076
2077
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2078
        $securityHandler
2079
            ->method('isGranted')
2080
            ->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...
2081
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2082
            });
2083
2084
        $admin->setSecurityHandler($securityHandler);
2085
2086
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2087
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2088
    }
2089
2090
    public function testDefaultFilters(): void
2091
    {
2092
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'SonataFooBundle:ModelAdmin');
2093
2094
        $subjectId = uniqid();
2095
2096
        $request = $this->createMock(Request::class);
2097
        $query = $this->createMock(ParameterBag::class);
2098
        $query
2099
            ->method('get')
2100
            ->with($this->equalTo('filter'))
2101
            ->willReturn([
2102
                'a' => [
2103
                    'value' => 'b',
2104
                ],
2105
                'foo' => [
2106
                    'type' => '1',
2107
                    'value' => 'bar',
2108
                ],
2109
                'baz' => [
2110
                    'type' => '5',
2111
                    'value' => 'test',
2112
                ],
2113
            ]);
2114
        $request->query = $query;
2115
2116
        $request
2117
            ->method('get')
2118
            ->willReturn($subjectId);
2119
2120
        $admin->setRequest($request);
2121
2122
        $modelManager = $this->createMock(ModelManagerInterface::class);
2123
        $modelManager
2124
            ->method('getDefaultSortValues')
2125
            ->willReturn([]);
2126
2127
        $admin->setModelManager($modelManager);
2128
2129
        $this->assertSame([
2130
            '_page' => 1,
2131
            '_per_page' => 32,
2132
            'foo' => [
2133
                'type' => '1',
2134
                'value' => 'bar',
2135
            ],
2136
            'baz' => [
2137
                'type' => '5',
2138
                'value' => 'test',
2139
            ],
2140
            'a' => [
2141
                'value' => 'b',
2142
            ],
2143
        ], $admin->getFilterParameters());
2144
2145
        $this->assertTrue($admin->isDefaultFilter('foo'));
2146
        $this->assertFalse($admin->isDefaultFilter('bar'));
2147
        $this->assertFalse($admin->isDefaultFilter('a'));
2148
    }
2149
2150
    /**
2151
     * @group legacy
2152
     */
2153
    public function testDefaultBreadcrumbsBuilder(): void
2154
    {
2155
        $container = $this->createMock(ContainerInterface::class);
2156
        $container->expects($this->once())
2157
            ->method('getParameter')
2158
            ->with('sonata.admin.configuration.breadcrumbs')
2159
            ->willReturn([]);
2160
2161
        $pool = $this->getMockBuilder(Pool::class)
2162
            ->disableOriginalConstructor()
2163
            ->getMock();
2164
        $pool->expects($this->once())
2165
            ->method('getContainer')
2166
            ->willReturn($container);
2167
2168
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2169
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2170
        ], '', true, true, true, ['getConfigurationPool']);
2171
        $admin->expects($this->once())
2172
            ->method('getConfigurationPool')
2173
            ->willReturn($pool);
2174
2175
        $this->assertInstanceOf(BreadcrumbsBuilder::class, $admin->getBreadcrumbsBuilder());
2176
    }
2177
2178
    /**
2179
     * @group legacy
2180
     */
2181
    public function testBreadcrumbsBuilderSetter(): void
2182
    {
2183
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2184
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2185
        ]);
2186
        $this->assertSame($admin, $admin->setBreadcrumbsBuilder($builder = $this->createMock(
2187
            BreadcrumbsBuilderInterface::class
2188
        )));
2189
        $this->assertSame($builder, $admin->getBreadcrumbsBuilder());
2190
    }
2191
2192
    /**
2193
     * @group legacy
2194
     */
2195
    public function testGetBreadcrumbs(): void
2196
    {
2197
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2198
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2199
        ]);
2200
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2201
        $action = 'myaction';
2202
        $builder->getBreadcrumbs($admin, $action)->shouldBeCalled();
2203
        $admin->setBreadcrumbsBuilder($builder->reveal())->getBreadcrumbs($action);
2204
    }
2205
2206
    /**
2207
     * @group legacy
2208
     */
2209
    public function testBuildBreadcrumbs(): void
2210
    {
2211
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2212
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2213
        ]);
2214
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2215
        $action = 'myaction';
2216
        $menu = $this->createMock(ItemInterface::class);
2217
        $builder->buildBreadcrumbs($admin, $action, $menu)
2218
            ->shouldBeCalledTimes(1)
2219
            ->willReturn($menu);
2220
        $admin->setBreadcrumbsBuilder($builder->reveal());
2221
2222
        /* check the called is proxied only once */
2223
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2224
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2225
    }
2226
2227
    /**
2228
     * NEXT_MAJOR: remove this method.
2229
     *
2230
     * @group legacy
2231
     */
2232
    public function testCreateQueryLegacyCallWorks(): void
2233
    {
2234
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2235
            'admin.my_code', 'My\Class', 'MyBundle:ClassAdmin',
2236
        ]);
2237
        $modelManager = $this->createMock(ModelManagerInterface::class);
2238
        $modelManager->expects($this->once())
2239
            ->method('createQuery')
2240
            ->with('My\Class')
2241
            ->willReturn('a query');
2242
2243
        $admin->setModelManager($modelManager);
2244
        $this->assertSame('a query', $admin->createQuery('list'));
2245
    }
2246
2247
    public function testGetDataSourceIterator(): void
2248
    {
2249
        $datagrid = $this->createMock(DatagridInterface::class);
2250
        $datagrid->method('buildPager');
2251
2252
        $modelManager = $this->createMock(ModelManagerInterface::class);
2253
        $modelManager->method('getExportFields')->willReturn([
2254
            'field',
2255
            'foo',
2256
            'bar',
2257
        ]);
2258
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2259
            ->with($this->equalTo($datagrid), $this->equalTo([
2260
                'Feld' => 'field',
2261
                1 => 'foo',
2262
                2 => 'bar',
2263
            ]));
2264
2265
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2266
            ->disableOriginalConstructor()
2267
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2268
            ->getMockForAbstractClass();
2269
        $admin->method('getDatagrid')->willReturn($datagrid);
2270
        $admin->setModelManager($modelManager);
2271
2272
        $admin
2273
            ->method('getTranslationLabel')
2274
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2275
                return $context.'.'.$type.'_'.$label;
2276
            });
2277
        $admin
2278
            ->method('trans')
2279
            ->willReturnCallback(static function (string $label): string {
2280
                if ('export.label_field' === $label) {
2281
                    return 'Feld';
2282
                }
2283
2284
                return $label;
2285
            });
2286
2287
        $admin->getDataSourceIterator();
2288
    }
2289
2290
    public function testCircularChildAdmin(): void
2291
    {
2292
        $this->expectException(\RuntimeException::class);
2293
        $this->expectExceptionMessage(
2294
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2295
        );
2296
2297
        $postAdmin = new PostAdmin(
2298
            'sonata.post.admin.post',
2299
            'Application\Sonata\NewsBundle\Entity\Post',
2300
            'SonataNewsBundle:PostAdmin'
2301
        );
2302
        $commentAdmin = new CommentAdmin(
2303
            'sonata.post.admin.comment',
2304
            'Application\Sonata\NewsBundle\Entity\Comment',
2305
            'SonataNewsBundle:CommentAdmin'
2306
        );
2307
        $postAdmin->addChild($commentAdmin, 'post');
2308
        $commentAdmin->addChild($postAdmin, 'comment');
2309
    }
2310
2311
    public function testCircularChildAdminTripleLevel(): void
2312
    {
2313
        $this->expectException(\RuntimeException::class);
2314
        $this->expectExceptionMessage(
2315
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2316
        );
2317
2318
        $postAdmin = new PostAdmin(
2319
            'sonata.post.admin.post',
2320
            'Application\Sonata\NewsBundle\Entity\Post',
2321
            'SonataNewsBundle:PostAdmin'
2322
        );
2323
        $commentAdmin = new CommentAdmin(
2324
            'sonata.post.admin.comment',
2325
            'Application\Sonata\NewsBundle\Entity\Comment',
2326
            'SonataNewsBundle:CommentAdmin'
2327
        );
2328
        $commentVoteAdmin = new CommentVoteAdmin(
2329
            'sonata.post.admin.comment_vote',
2330
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2331
            'SonataNewsBundle:CommentVoteAdmin'
2332
        );
2333
        $postAdmin->addChild($commentAdmin, 'post');
2334
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2335
        $commentVoteAdmin->addChild($postAdmin, 'post');
2336
    }
2337
2338
    public function testCircularChildAdminWithItself(): void
2339
    {
2340
        $this->expectException(\RuntimeException::class);
2341
        $this->expectExceptionMessage(
2342
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2343
        );
2344
2345
        $postAdmin = new PostAdmin(
2346
            'sonata.post.admin.post',
2347
            'Application\Sonata\NewsBundle\Entity\Post',
2348
            'SonataNewsBundle:PostAdmin'
2349
        );
2350
        $postAdmin->addChild($postAdmin);
2351
    }
2352
2353
    public function testGetRootAncestor(): void
2354
    {
2355
        $postAdmin = new PostAdmin(
2356
            'sonata.post.admin.post',
2357
            'Application\Sonata\NewsBundle\Entity\Post',
2358
            'SonataNewsBundle:PostAdmin'
2359
        );
2360
        $commentAdmin = new CommentAdmin(
2361
            'sonata.post.admin.comment',
2362
            'Application\Sonata\NewsBundle\Entity\Comment',
2363
            'SonataNewsBundle:CommentAdmin'
2364
        );
2365
        $commentVoteAdmin = new CommentVoteAdmin(
2366
            'sonata.post.admin.comment_vote',
2367
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2368
            'SonataNewsBundle:CommentVoteAdmin'
2369
        );
2370
2371
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2372
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2373
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2374
2375
        $postAdmin->addChild($commentAdmin, 'post');
2376
2377
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2378
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2379
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2380
2381
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2382
2383
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2384
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2385
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2386
    }
2387
2388
    public function testGetChildDepth(): void
2389
    {
2390
        $postAdmin = new PostAdmin(
2391
            'sonata.post.admin.post',
2392
            'Application\Sonata\NewsBundle\Entity\Post',
2393
            'SonataNewsBundle:PostAdmin'
2394
        );
2395
        $commentAdmin = new CommentAdmin(
2396
            'sonata.post.admin.comment',
2397
            'Application\Sonata\NewsBundle\Entity\Comment',
2398
            'SonataNewsBundle:CommentAdmin'
2399
        );
2400
        $commentVoteAdmin = new CommentVoteAdmin(
2401
            'sonata.post.admin.comment_vote',
2402
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2403
            'SonataNewsBundle:CommentVoteAdmin'
2404
        );
2405
2406
        $this->assertSame(0, $postAdmin->getChildDepth());
2407
        $this->assertSame(0, $commentAdmin->getChildDepth());
2408
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2409
2410
        $postAdmin->addChild($commentAdmin, 'post');
2411
2412
        $this->assertSame(0, $postAdmin->getChildDepth());
2413
        $this->assertSame(1, $commentAdmin->getChildDepth());
2414
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2415
2416
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2417
2418
        $this->assertSame(0, $postAdmin->getChildDepth());
2419
        $this->assertSame(1, $commentAdmin->getChildDepth());
2420
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2421
    }
2422
2423
    public function testGetCurrentLeafChildAdmin(): void
2424
    {
2425
        $postAdmin = new PostAdmin(
2426
            'sonata.post.admin.post',
2427
            'Application\Sonata\NewsBundle\Entity\Post',
2428
            'SonataNewsBundle:PostAdmin'
2429
        );
2430
        $commentAdmin = new CommentAdmin(
2431
            'sonata.post.admin.comment',
2432
            'Application\Sonata\NewsBundle\Entity\Comment',
2433
            'SonataNewsBundle:CommentAdmin'
2434
        );
2435
        $commentVoteAdmin = new CommentVoteAdmin(
2436
            'sonata.post.admin.comment_vote',
2437
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2438
            'SonataNewsBundle:CommentVoteAdmin'
2439
        );
2440
2441
        $postAdmin->addChild($commentAdmin, 'post');
2442
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2443
2444
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2445
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2446
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2447
2448
        $commentAdmin->setCurrentChild(true);
2449
2450
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2451
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2452
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2453
2454
        $commentVoteAdmin->setCurrentChild(true);
2455
2456
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2457
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2458
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2459
    }
2460
2461
    private function createTagAdmin(Post $post): TagAdmin
2462
    {
2463
        $postAdmin = $this->getMockBuilder(PostAdmin::class)
2464
            ->disableOriginalConstructor()
2465
            ->getMock();
2466
2467
        $postAdmin->method('getObject')->willReturn($post);
2468
2469
        $formBuilder = $this->createMock(FormBuilderInterface::class);
2470
        $formBuilder->method('getForm')->willReturn(null);
2471
2472
        $tagAdmin = $this->getMockBuilder(TagAdmin::class)
2473
            ->setConstructorArgs([
2474
                'admin.tag',
2475
                Tag::class,
2476
                'MyBundle:MyController',
2477
            ])
2478
            ->setMethods(['getFormBuilder'])
2479
            ->getMock();
2480
2481
        $tagAdmin->method('getFormBuilder')->willReturn($formBuilder);
2482
        $tagAdmin->setParent($postAdmin);
2483
2484
        $tag = new Tag();
2485
        $tagAdmin->setSubject($tag);
2486
2487
        $request = $this->createMock(Request::class);
2488
        $tagAdmin->setRequest($request);
2489
2490
        $configurationPool = $this->getMockBuilder(Pool::class)
2491
            ->disableOriginalConstructor()
2492
            ->getMock();
2493
2494
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
2495
2496
        $tagAdmin->setConfigurationPool($configurationPool);
2497
2498
        return $tagAdmin;
2499
    }
2500
}
2501