Completed
Push — 3.x ( cd4ff0...3fa3f4 )
by Jordi Sala
03:07
created

AdminTest::testCantAccessObjectIfNullPassed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

Loading history...
854
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
855
    }
856
857
    public function testGetLabelTranslatorStrategy(): void
858
    {
859
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
860
861
        $this->assertNull($admin->getLabelTranslatorStrategy());
862
863
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
864
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
865
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
866
    }
867
868
    public function testGetRouteBuilder(): void
869
    {
870
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
871
872
        $this->assertNull($admin->getRouteBuilder());
873
874
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
875
        $admin->setRouteBuilder($routeBuilder);
876
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
877
    }
878
879
    public function testGetMenuFactory(): void
880
    {
881
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
882
883
        $this->assertNull($admin->getMenuFactory());
884
885
        $menuFactory = $this->createMock(FactoryInterface::class);
886
        $admin->setMenuFactory($menuFactory);
887
        $this->assertSame($menuFactory, $admin->getMenuFactory());
888
    }
889
890
    public function testGetExtensions(): void
891
    {
892
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
893
894
        $this->assertSame([], $admin->getExtensions());
895
896
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
897
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
898
899
        $admin->addExtension($adminExtension1);
900
        $admin->addExtension($adminExtension2);
901
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
902
    }
903
904
    public function testGetFilterTheme(): void
905
    {
906
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
907
908
        $this->assertSame([], $admin->getFilterTheme());
909
910
        $admin->setFilterTheme(['FooTheme']);
911
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
912
    }
913
914
    public function testGetFormTheme(): void
915
    {
916
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
917
918
        $this->assertSame([], $admin->getFormTheme());
919
920
        $admin->setFormTheme(['FooTheme']);
921
922
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
923
    }
924
925
    public function testGetValidator(): void
926
    {
927
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
928
929
        $this->assertNull($admin->getValidator());
930
931
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
932
933
        $admin->setValidator($validator);
934
        $this->assertSame($validator, $admin->getValidator());
935
    }
936
937
    public function testGetSecurityHandler(): void
938
    {
939
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
940
941
        $this->assertNull($admin->getSecurityHandler());
942
943
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
944
        $admin->setSecurityHandler($securityHandler);
945
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
946
    }
947
948
    public function testGetSecurityInformation(): void
949
    {
950
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
951
952
        $this->assertSame([], $admin->getSecurityInformation());
953
954
        $securityInformation = [
955
            'GUEST' => ['VIEW', 'LIST'],
956
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
957
        ];
958
959
        $admin->setSecurityInformation($securityInformation);
960
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
961
    }
962
963
    public function testGetManagerType(): void
964
    {
965
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
966
967
        $this->assertNull($admin->getManagerType());
968
969
        $admin->setManagerType('foo_orm');
970
        $this->assertSame('foo_orm', $admin->getManagerType());
971
    }
972
973
    public function testGetModelManager(): void
974
    {
975
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
976
977
        $this->assertNull($admin->getModelManager());
978
979
        $modelManager = $this->createMock(ModelManagerInterface::class);
980
981
        $admin->setModelManager($modelManager);
982
        $this->assertSame($modelManager, $admin->getModelManager());
983
    }
984
985
    /**
986
     * NEXT_MAJOR: remove this method.
987
     *
988
     * @group legacy
989
     */
990
    public function testGetBaseCodeRoute(): void
991
    {
992
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
993
994
        $this->assertSame('', $admin->getBaseCodeRoute());
995
996
        $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...
997
        $this->assertSame('foo', $admin->getBaseCodeRoute());
998
    }
999
1000
    // NEXT_MAJOR: uncomment this method.
1001
    // public function testGetBaseCodeRoute()
1002
    // {
1003
    //     $postAdmin = new PostAdmin(
1004
    //         'sonata.post.admin.post',
1005
    //         'NewsBundle\Entity\Post',
1006
    //         'Sonata\NewsBundle\Controller\PostAdminController'
1007
    //     );
1008
    //     $commentAdmin = new CommentAdmin(
1009
    //         'sonata.post.admin.comment',
1010
    //         'Application\Sonata\NewsBundle\Entity\Comment',
1011
    //         'Sonata\NewsBundle\Controller\CommentAdminController'
1012
    //     );
1013
    //
1014
    //     $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
1015
    //
1016
    //     $postAdmin->addChild($commentAdmin);
1017
    //
1018
    //     $this->assertSame(
1019
    //         'sonata.post.admin.post|sonata.post.admin.comment',
1020
    //         $commentAdmin->getBaseCodeRoute()
1021
    //     );
1022
    // }
1023
1024
    public function testGetRouteGenerator(): void
1025
    {
1026
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1027
1028
        $this->assertNull($admin->getRouteGenerator());
1029
1030
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1031
1032
        $admin->setRouteGenerator($routeGenerator);
1033
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1034
    }
1035
1036
    public function testGetConfigurationPool(): void
1037
    {
1038
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1039
1040
        $this->assertNull($admin->getConfigurationPool());
1041
1042
        $pool = $this->getMockBuilder(Pool::class)
1043
            ->disableOriginalConstructor()
1044
            ->getMock();
1045
1046
        $admin->setConfigurationPool($pool);
1047
        $this->assertSame($pool, $admin->getConfigurationPool());
1048
    }
1049
1050
    public function testGetShowBuilder(): void
1051
    {
1052
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1053
1054
        $this->assertNull($admin->getShowBuilder());
1055
1056
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1057
1058
        $admin->setShowBuilder($showBuilder);
1059
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1060
    }
1061
1062
    public function testGetListBuilder(): void
1063
    {
1064
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1065
1066
        $this->assertNull($admin->getListBuilder());
1067
1068
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1069
1070
        $admin->setListBuilder($listBuilder);
1071
        $this->assertSame($listBuilder, $admin->getListBuilder());
1072
    }
1073
1074
    public function testGetDatagridBuilder(): void
1075
    {
1076
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1077
1078
        $this->assertNull($admin->getDatagridBuilder());
1079
1080
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1081
1082
        $admin->setDatagridBuilder($datagridBuilder);
1083
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1084
    }
1085
1086
    public function testGetFormContractor(): void
1087
    {
1088
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1089
1090
        $this->assertNull($admin->getFormContractor());
1091
1092
        $formContractor = $this->createMock(FormContractorInterface::class);
1093
1094
        $admin->setFormContractor($formContractor);
1095
        $this->assertSame($formContractor, $admin->getFormContractor());
1096
    }
1097
1098
    public function testGetRequest(): void
1099
    {
1100
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1101
1102
        $this->assertFalse($admin->hasRequest());
1103
1104
        $request = new Request();
1105
1106
        $admin->setRequest($request);
1107
        $this->assertSame($request, $admin->getRequest());
1108
        $this->assertTrue($admin->hasRequest());
1109
    }
1110
1111
    public function testGetRequestWithException(): void
1112
    {
1113
        $this->expectException(\RuntimeException::class);
1114
        $this->expectExceptionMessage('The Request object has not been set');
1115
1116
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1117
        $admin->getRequest();
1118
    }
1119
1120
    public function testGetTranslationDomain(): void
1121
    {
1122
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1123
1124
        $this->assertSame('messages', $admin->getTranslationDomain());
1125
1126
        $admin->setTranslationDomain('foo');
1127
        $this->assertSame('foo', $admin->getTranslationDomain());
1128
    }
1129
1130
    /**
1131
     * @group legacy
1132
     */
1133
    public function testGetTranslator(): void
1134
    {
1135
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1136
1137
        $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...
1138
1139
        $translator = $this->createMock(TranslatorInterface::class);
1140
1141
        $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...
1142
        $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...
1143
    }
1144
1145
    public function testGetShowGroups(): void
1146
    {
1147
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1148
1149
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1150
        $this->assertFalse($admin->getShowGroups('sonata_deprecation_mute'));
1151
1152
        $groups = ['foo', 'bar', 'baz'];
1153
1154
        $admin->setShowGroups($groups);
1155
        $this->assertSame($groups, $admin->getShowGroups());
1156
    }
1157
1158
    public function testGetFormGroups(): void
1159
    {
1160
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1161
1162
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1163
        $this->assertFalse($admin->getFormGroups('sonata_deprecation_mute'));
1164
1165
        $groups = ['foo', 'bar', 'baz'];
1166
1167
        $admin->setFormGroups($groups);
1168
        $this->assertSame($groups, $admin->getFormGroups());
1169
    }
1170
1171
    public function testGetMaxPageLinks(): void
1172
    {
1173
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1174
1175
        $this->assertSame(25, $admin->getMaxPageLinks());
1176
1177
        $admin->setMaxPageLinks(14);
1178
        $this->assertSame(14, $admin->getMaxPageLinks());
1179
    }
1180
1181
    /**
1182
     * @group legacy
1183
     */
1184
    public function testGetMaxPerPage(): void
1185
    {
1186
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1187
1188
        $this->assertSame(32, $admin->getMaxPerPage());
1189
1190
        $admin->setMaxPerPage(94);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...tAdmin::setMaxPerPage() has been deprecated with message: since sonata-project/admin-bundle 3.67, to be removed in 4.0.

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

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

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