Completed
Pull Request — 3.x (#6162)
by
unknown
03:25 queued 11s
created

AdminTest::testOnlyOneSubclassNeededToBeActive()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
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 testGetFilterParametersWithoutRequest(): void
1882
    {
1883
        $authorId = uniqid();
1884
1885
        $postAdmin = new PostAdmin(
1886
            'sonata.post.admin.post',
1887
            'Application\Sonata\NewsBundle\Entity\Post',
1888
            'Sonata\NewsBundle\Controller\PostAdminController'
1889
        );
1890
1891
        $commentAdmin = new CommentAdmin(
1892
            'sonata.post.admin.comment',
1893
            'Application\Sonata\NewsBundle\Entity\Comment',
1894
            'Sonata\NewsBundle\Controller\CommentAdminController'
1895
        );
1896
        $commentAdmin->setParentAssociationMapping('post.author');
1897
        $commentAdmin->setParent($postAdmin);
1898
1899
        $modelManager = $this->createStub(ModelManagerInterface::class);
1900
        $modelManager
1901
            ->method('getDefaultSortValues')
1902
            ->willReturn([])
1903
        ;
1904
1905
        $commentAdmin->setModelManager($modelManager);
1906
1907
        $parameters = $commentAdmin->getFilterParameters();
1908
1909
        $this->assertArrayHasKey('post__author', $parameters);
1910
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1911
    }
1912
1913
    public function testGetFilterFieldDescription(): void
1914
    {
1915
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1916
1917
        $fooFieldDescription = new FieldDescription();
1918
        $barFieldDescription = new FieldDescription();
1919
        $bazFieldDescription = new FieldDescription();
1920
1921
        $modelManager = $this->createMock(ModelManagerInterface::class);
1922
        $modelManager
1923
            ->method('getDefaultSortValues')
1924
            ->willReturn([]);
1925
1926
        $modelManager->expects($this->exactly(3))
1927
            ->method('getNewFieldDescriptionInstance')
1928
            ->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...
1929
                switch ($name) {
1930
                    case 'foo':
1931
                        $fieldDescription = $fooFieldDescription;
1932
1933
                        break;
1934
1935
                    case 'bar':
1936
                        $fieldDescription = $barFieldDescription;
1937
1938
                        break;
1939
1940
                    case 'baz':
1941
                        $fieldDescription = $bazFieldDescription;
1942
1943
                        break;
1944
1945
                    default:
1946
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1947
                        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...
1948
                }
1949
1950
                $fieldDescription->setName($name);
1951
1952
                return $fieldDescription;
1953
            });
1954
1955
        $modelAdmin->setModelManager($modelManager);
1956
1957
        $pager = $this->createMock(PagerInterface::class);
1958
1959
        $datagrid = $this->createMock(DatagridInterface::class);
1960
        $datagrid->expects($this->once())
1961
            ->method('getPager')
1962
            ->willReturn($pager);
1963
1964
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1965
        $datagridBuilder->expects($this->once())
1966
            ->method('getBaseDatagrid')
1967
            ->with($this->identicalTo($modelAdmin), [])
1968
            ->willReturn($datagrid);
1969
1970
        $datagridBuilder->expects($this->exactly(3))
1971
            ->method('addFilter')
1972
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1973
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1974
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1975
            });
1976
1977
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1978
1979
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1980
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1981
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1982
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1983
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1984
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1985
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1986
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1987
    }
1988
1989
    public function testGetSubjectNoRequest(): void
1990
    {
1991
        $modelManager = $this->createMock(ModelManagerInterface::class);
1992
        $modelManager
1993
            ->expects($this->never())
1994
            ->method('find');
1995
1996
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1997
        $admin->setModelManager($modelManager);
1998
1999
        $this->assertFalse($admin->hasSubject());
2000
    }
2001
2002
    public function testGetSideMenu(): void
2003
    {
2004
        $item = $this->createMock(ItemInterface::class);
2005
        $item
2006
            ->expects($this->once())
2007
            ->method('setChildrenAttribute')
2008
            ->with('class', 'nav navbar-nav');
2009
        $item
2010
            ->expects($this->once())
2011
            ->method('setExtra')
2012
            ->with('translation_domain', 'foo_bar_baz');
2013
2014
        $menuFactory = $this->createMock(FactoryInterface::class);
2015
        $menuFactory
2016
            ->expects($this->once())
2017
            ->method('createItem')
2018
            ->willReturn($item);
2019
2020
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2021
        $modelAdmin->setMenuFactory($menuFactory);
2022
        $modelAdmin->setTranslationDomain('foo_bar_baz');
2023
2024
        $modelAdmin->getSideMenu('foo');
2025
    }
2026
2027
    /**
2028
     * @return array
2029
     */
2030
    public function provideGetSubject()
2031
    {
2032
        return [
2033
            [23],
2034
            ['azerty'],
2035
            ['4f69bbb5f14a13347f000092'],
2036
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
2037
            [sprintf('123%smy_type', AdapterInterface::ID_SEPARATOR)], // composite keys are supported
2038
        ];
2039
    }
2040
2041
    /**
2042
     * @dataProvider provideGetSubject
2043
     */
2044
    public function testGetSubjectFailed($id): void
2045
    {
2046
        $modelManager = $this->createMock(ModelManagerInterface::class);
2047
        $modelManager
2048
            ->expects($this->once())
2049
            ->method('find')
2050
            ->with('NewsBundle\Entity\Post', $id)
2051
            ->willReturn(null); // entity not found
2052
2053
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2054
        $admin->setModelManager($modelManager);
2055
2056
        $admin->setRequest(new Request(['id' => $id]));
2057
        $this->assertFalse($admin->hasSubject());
2058
    }
2059
2060
    /**
2061
     * @dataProvider provideGetSubject
2062
     */
2063
    public function testGetSubject($id): void
2064
    {
2065
        $model = new Post();
2066
2067
        $modelManager = $this->createMock(ModelManagerInterface::class);
2068
        $modelManager
2069
            ->expects($this->once())
2070
            ->method('find')
2071
            ->with('NewsBundle\Entity\Post', $id)
2072
            ->willReturn($model);
2073
2074
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2075
        $admin->setModelManager($modelManager);
2076
2077
        $admin->setRequest(new Request(['id' => $id]));
2078
        $this->assertTrue($admin->hasSubject());
2079
        $this->assertSame($model, $admin->getSubject());
2080
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
2081
    }
2082
2083
    public function testGetSubjectWithParentDescription(): void
2084
    {
2085
        $adminId = 1;
2086
2087
        $comment = new Comment();
2088
2089
        $modelManager = $this->createMock(ModelManagerInterface::class);
2090
        $modelManager
2091
            ->method('find')
2092
            ->with('NewsBundle\Entity\Comment', $adminId)
2093
            ->willReturn($comment);
2094
2095
        $request = new Request(['id' => $adminId]);
2096
2097
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2098
        $postAdmin->setRequest($request);
2099
2100
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
2101
        $commentAdmin->setRequest($request);
2102
        $commentAdmin->setModelManager($modelManager);
2103
2104
        $this->assertTrue($commentAdmin->hasSubject());
2105
        $this->assertSame($comment, $commentAdmin->getSubject());
2106
2107
        $commentAdmin->setSubject(null);
2108
        $commentAdmin->setParentFieldDescription(new FieldDescription());
2109
2110
        $this->assertFalse($commentAdmin->hasSubject());
2111
    }
2112
2113
    /**
2114
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2115
     */
2116
    public function testGetActionButtonsList(): void
2117
    {
2118
        $expected = [
2119
            'create' => [
2120
                'template' => 'Foo.html.twig',
2121
            ],
2122
        ];
2123
2124
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2125
2126
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2127
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
2128
2129
        $admin->setTemplateRegistry($templateRegistry->reveal());
2130
2131
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2132
        $securityHandler
2133
            ->expects($this->once())
2134
            ->method('isGranted')
2135
            ->with($admin, 'CREATE', $admin)
2136
            ->willReturn(true);
2137
        $admin->setSecurityHandler($securityHandler);
2138
2139
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2140
        $routeGenerator
2141
            ->expects($this->once())
2142
            ->method('hasAdminRoute')
2143
            ->with($admin, 'create')
2144
            ->willReturn(true);
2145
        $admin->setRouteGenerator($routeGenerator);
2146
2147
        $this->assertSame($expected, $admin->getActionButtons('list', null));
2148
    }
2149
2150
    /**
2151
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2152
     */
2153
    public function testGetActionButtonsListCreateDisabled(): void
2154
    {
2155
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2156
2157
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2158
        $securityHandler
2159
            ->expects($this->once())
2160
            ->method('isGranted')
2161
            ->with($admin, 'CREATE', $admin)
2162
            ->willReturn(false);
2163
        $admin->setSecurityHandler($securityHandler);
2164
2165
        $this->assertSame([], $admin->getActionButtons('list', null));
2166
    }
2167
2168
    public function testCantAccessObjectIfNullPassed(): void
2169
    {
2170
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2171
2172
        $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...
2173
    }
2174
2175
    public function testCantAccessObjectIfRandomObjectPassed(): void
2176
    {
2177
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2178
        $modelManager = $this->createMock(ModelManagerInterface::class);
2179
        $admin->setModelManager($modelManager);
2180
2181
        $this->assertFalse($admin->canAccessObject('list', new \stdClass()));
2182
    }
2183
2184
    public function testCanAccessObject(): void
2185
    {
2186
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2187
        $modelManager = $this->createMock(ModelManagerInterface::class);
2188
        $modelManager
2189
            ->method('getNormalizedIdentifier')
2190
            ->willReturn('identifier');
2191
        $admin->setModelManager($modelManager);
2192
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2193
        $admin->setSecurityHandler($securityHandler);
2194
2195
        $this->assertTrue($admin->canAccessObject('list', new \stdClass()));
2196
    }
2197
2198
    /**
2199
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions
2200
     */
2201
    public function testGetBatchActions(): void
2202
    {
2203
        $expected = [
2204
            'delete' => [
2205
                'label' => 'action_delete',
2206
                'translation_domain' => 'SonataAdminBundle',
2207
                'ask_confirmation' => true, // by default always true
2208
            ],
2209
            'foo' => [
2210
                'label' => 'action_foo',
2211
                'translation_domain' => 'SonataAdminBundle',
2212
            ],
2213
            'bar' => [
2214
                'label' => 'batch.label_bar',
2215
                'translation_domain' => 'SonataAdminBundle',
2216
            ],
2217
            'baz' => [
2218
                'label' => 'action_baz',
2219
                'translation_domain' => 'AcmeAdminBundle',
2220
            ],
2221
        ];
2222
2223
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2224
2225
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
2226
        $labelTranslatorStrategy
2227
            ->method('getLabel')
2228
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2229
                return sprintf('%s.%s_%s', $context, $type, $label);
2230
            });
2231
2232
        $admin = new PostAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2233
        $admin->setRouteBuilder($pathInfo);
2234
        $admin->setTranslationDomain('SonataAdminBundle');
2235
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
2236
2237
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2238
        $routeGenerator
2239
            ->expects($this->once())
2240
            ->method('hasAdminRoute')
2241
            ->with($admin, 'delete')
2242
            ->willReturn(true);
2243
        $admin->setRouteGenerator($routeGenerator);
2244
2245
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2246
        $securityHandler
2247
            ->method('isGranted')
2248
            ->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...
2249
                return $admin === $adminIn && 'DELETE' === $attributes;
2250
            });
2251
        $admin->setSecurityHandler($securityHandler);
2252
2253
        $this->assertSame($expected, $admin->getBatchActions());
2254
    }
2255
2256
    /**
2257
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2258
     */
2259
    public function testShowMosaicButton(): void
2260
    {
2261
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2262
        $listModes = $admin->getListModes();
2263
2264
        $admin->showMosaicButton(true);
2265
2266
        $this->assertSame($listModes, $admin->getListModes());
2267
    }
2268
2269
    /**
2270
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::showMosaicButton
2271
     */
2272
    public function testShowMosaicButtonHideMosaic(): void
2273
    {
2274
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2275
        $listModes = $admin->getListModes();
2276
        $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...
2277
2278
        $admin->showMosaicButton(false);
2279
2280
        $this->assertSame($expected, $admin->getListModes());
2281
    }
2282
2283
    /**
2284
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getDashboardActions
2285
     * @dataProvider provideGetBaseRouteName
2286
     */
2287
    public function testDefaultDashboardActionsArePresent(string $objFqn, string $expected): void
2288
    {
2289
        $pathInfo = new PathInfoBuilder($this->createMock(AuditManagerInterface::class));
2290
2291
        $routeGenerator = new DefaultRouteGenerator(
2292
            $this->createMock(RouterInterface::class),
2293
            new RoutesCache($this->cacheTempFolder, true)
2294
        );
2295
2296
        $admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'Sonata\NewsBundle\Controller\PostAdminController');
2297
        $admin->setRouteBuilder($pathInfo);
2298
        $admin->setRouteGenerator($routeGenerator);
2299
        $admin->initialize();
2300
2301
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2302
        $templateRegistry->getTemplate('action_create')->willReturn('Foo.html.twig');
2303
2304
        $admin->setTemplateRegistry($templateRegistry->reveal());
2305
2306
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2307
        $securityHandler
2308
            ->method('isGranted')
2309
            ->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...
2310
                return $admin === $adminIn && ('CREATE' === $attributes || 'LIST' === $attributes);
2311
            });
2312
2313
        $admin->setSecurityHandler($securityHandler);
2314
2315
        $this->assertArrayHasKey('list', $admin->getDashboardActions());
2316
        $this->assertArrayHasKey('create', $admin->getDashboardActions());
2317
    }
2318
2319
    /**
2320
     * NEXT_MAJOR: Remove the assertion about isDefaultFilter method and the legacy group.
2321
     *
2322
     * @group legacy
2323
     *
2324
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::isDefaultFilter" is deprecated since sonata-project/admin-bundle 3.x.
2325
     */
2326
    public function testDefaultFilters(): void
2327
    {
2328
        $admin = new FilteredAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
2329
2330
        $subjectId = uniqid();
2331
2332
        $request = $this->createMock(Request::class);
2333
        $query = $this->createMock(ParameterBag::class);
2334
        $query
2335
            ->method('get')
2336
            ->with($this->equalTo('filter'))
2337
            ->willReturn([
2338
                'a' => [
2339
                    'value' => 'b',
2340
                ],
2341
                'foo' => [
2342
                    'type' => '1',
2343
                    'value' => 'bar',
2344
                ],
2345
                'baz' => [
2346
                    'type' => '5',
2347
                    'value' => 'test',
2348
                ],
2349
            ]);
2350
        $request->query = $query;
2351
2352
        $request
2353
            ->method('get')
2354
            ->willReturn($subjectId);
2355
2356
        $admin->setRequest($request);
2357
2358
        $modelManager = $this->createMock(ModelManagerInterface::class);
2359
        $modelManager
2360
            ->method('getDefaultSortValues')
2361
            ->willReturn([]);
2362
2363
        $admin->setModelManager($modelManager);
2364
2365
        $this->assertSame([
2366
            '_page' => 1,
2367
            '_per_page' => 32,
2368
            'foo' => [
2369
                'type' => '1',
2370
                'value' => 'bar',
2371
            ],
2372
            'baz' => [
2373
                'type' => '5',
2374
                'value' => 'test',
2375
            ],
2376
            'a' => [
2377
                'value' => 'b',
2378
            ],
2379
        ], $admin->getFilterParameters());
2380
2381
        $this->assertTrue($admin->isDefaultFilter('foo'));
2382
        $this->assertFalse($admin->isDefaultFilter('bar'));
2383
        $this->assertFalse($admin->isDefaultFilter('a'));
2384
    }
2385
2386
    /**
2387
     * @group legacy
2388
     */
2389
    public function testDefaultBreadcrumbsBuilder(): void
2390
    {
2391
        $container = $this->createMock(ContainerInterface::class);
2392
        $container->expects($this->once())
2393
            ->method('getParameter')
2394
            ->with('sonata.admin.configuration.breadcrumbs')
2395
            ->willReturn([]);
2396
2397
        $pool = $this->getMockBuilder(Pool::class)
2398
            ->disableOriginalConstructor()
2399
            ->getMock();
2400
        $pool->expects($this->once())
2401
            ->method('getContainer')
2402
            ->willReturn($container);
2403
2404
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2405
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2406
        ], '', true, true, true, ['getConfigurationPool']);
2407
        $admin->expects($this->once())
2408
            ->method('getConfigurationPool')
2409
            ->willReturn($pool);
2410
2411
        $this->assertInstanceOf(BreadcrumbsBuilder::class, $admin->getBreadcrumbsBuilder());
2412
    }
2413
2414
    /**
2415
     * @group legacy
2416
     */
2417
    public function testBreadcrumbsBuilderSetter(): void
2418
    {
2419
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2420
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2421
        ]);
2422
        $this->assertSame($admin, $admin->setBreadcrumbsBuilder($builder = $this->createMock(
2423
            BreadcrumbsBuilderInterface::class
2424
        )));
2425
        $this->assertSame($builder, $admin->getBreadcrumbsBuilder());
2426
    }
2427
2428
    /**
2429
     * @group legacy
2430
     */
2431
    public function testGetBreadcrumbs(): void
2432
    {
2433
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2434
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2435
        ]);
2436
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2437
        $action = 'myaction';
2438
        $builder->getBreadcrumbs($admin, $action)->shouldBeCalled();
2439
        $admin->setBreadcrumbsBuilder($builder->reveal())->getBreadcrumbs($action);
2440
    }
2441
2442
    /**
2443
     * @group legacy
2444
     */
2445
    public function testBuildBreadcrumbs(): void
2446
    {
2447
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2448
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2449
        ]);
2450
        $builder = $this->prophesize(BreadcrumbsBuilderInterface::class);
2451
        $action = 'myaction';
2452
        $menu = $this->createMock(ItemInterface::class);
2453
        $builder->buildBreadcrumbs($admin, $action, $menu)
2454
            ->shouldBeCalledTimes(1)
2455
            ->willReturn($menu);
2456
        $admin->setBreadcrumbsBuilder($builder->reveal());
2457
2458
        /* check the called is proxied only once */
2459
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2460
        $this->assertSame($menu, $admin->buildBreadcrumbs($action, $menu));
2461
    }
2462
2463
    /**
2464
     * NEXT_MAJOR: remove this method.
2465
     *
2466
     * @group legacy
2467
     */
2468
    public function testCreateQueryLegacyCallWorks(): void
2469
    {
2470
        $admin = $this->getMockForAbstractClass(AbstractAdmin::class, [
2471
            'admin.my_code', 'My\Class', 'MyBundle\ClassAdminController',
2472
        ]);
2473
        $query = $this->createMock(ProxyQueryInterface::class);
2474
        $modelManager = $this->createMock(ModelManagerInterface::class);
2475
        $modelManager->expects($this->once())
2476
            ->method('createQuery')
2477
            ->with('My\Class')
2478
            ->willReturn($query);
2479
2480
        $admin->setModelManager($modelManager);
2481
        $this->assertSame($query, $admin->createQuery('list'));
2482
    }
2483
2484
    public function testGetDataSourceIterator(): void
2485
    {
2486
        $datagrid = $this->createMock(DatagridInterface::class);
2487
        $datagrid->method('buildPager');
2488
2489
        $modelManager = $this->createMock(ModelManagerInterface::class);
2490
        $modelManager->method('getExportFields')->willReturn([
2491
            'field',
2492
            'foo',
2493
            'bar',
2494
        ]);
2495
        $modelManager->expects($this->once())->method('getDataSourceIterator')
2496
            ->with($this->equalTo($datagrid), $this->equalTo([
2497
                'Feld' => 'field',
2498
                1 => 'foo',
2499
                2 => 'bar',
2500
            ]));
2501
2502
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2503
            ->disableOriginalConstructor()
2504
            ->setMethods(['getDatagrid', 'getTranslationLabel', 'trans'])
2505
            ->getMockForAbstractClass();
2506
        $admin->method('getDatagrid')->willReturn($datagrid);
2507
        $admin->setModelManager($modelManager);
2508
2509
        $admin
2510
            ->method('getTranslationLabel')
2511
            ->willReturnCallback(static function (string $label, string $context = '', string $type = ''): string {
2512
                return sprintf('%s.%s_%s', $context, $type, $label);
2513
            });
2514
        $admin
2515
            ->method('trans')
2516
            ->willReturnCallback(static function (string $label): string {
2517
                if ('export.label_field' === $label) {
2518
                    return 'Feld';
2519
                }
2520
2521
                return $label;
2522
            });
2523
2524
        $admin->getDataSourceIterator();
2525
    }
2526
2527
    public function testCircularChildAdmin(): void
2528
    {
2529
        $this->expectException(\RuntimeException::class);
2530
        $this->expectExceptionMessage(
2531
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment` admin.'
2532
        );
2533
2534
        $postAdmin = new PostAdmin(
2535
            'sonata.post.admin.post',
2536
            'Application\Sonata\NewsBundle\Entity\Post',
2537
            'Sonata\NewsBundle\Controller\PostAdminController'
2538
        );
2539
        $commentAdmin = new CommentAdmin(
2540
            'sonata.post.admin.comment',
2541
            'Application\Sonata\NewsBundle\Entity\Comment',
2542
            'Sonata\NewsBundle\Controller\CommentAdminController'
2543
        );
2544
        $postAdmin->addChild($commentAdmin, 'post');
2545
        $commentAdmin->addChild($postAdmin, 'comment');
2546
    }
2547
2548
    public function testCircularChildAdminTripleLevel(): void
2549
    {
2550
        $this->expectException(\RuntimeException::class);
2551
        $this->expectExceptionMessage(
2552
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.comment_vote` admin.'
2553
        );
2554
2555
        $postAdmin = new PostAdmin(
2556
            'sonata.post.admin.post',
2557
            'Application\Sonata\NewsBundle\Entity\Post',
2558
            'Sonata\NewsBundle\Controller\PostAdminController'
2559
        );
2560
        $commentAdmin = new CommentAdmin(
2561
            'sonata.post.admin.comment',
2562
            'Application\Sonata\NewsBundle\Entity\Comment',
2563
            'Sonata\NewsBundle\Controller\CommentAdminController'
2564
        );
2565
        $commentVoteAdmin = new CommentVoteAdmin(
2566
            'sonata.post.admin.comment_vote',
2567
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2568
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2569
        );
2570
        $postAdmin->addChild($commentAdmin, 'post');
2571
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2572
        $commentVoteAdmin->addChild($postAdmin, 'post');
2573
    }
2574
2575
    public function testCircularChildAdminWithItself(): void
2576
    {
2577
        $this->expectException(\RuntimeException::class);
2578
        $this->expectExceptionMessage(
2579
            'Circular reference detected! The child admin `sonata.post.admin.post` is already in the parent tree of the `sonata.post.admin.post` admin.'
2580
        );
2581
2582
        $postAdmin = new PostAdmin(
2583
            'sonata.post.admin.post',
2584
            'Application\Sonata\NewsBundle\Entity\Post',
2585
            'Sonata\NewsBundle\Controller\PostAdminController'
2586
        );
2587
        $postAdmin->addChild($postAdmin);
2588
    }
2589
2590
    public function testGetRootAncestor(): void
2591
    {
2592
        $postAdmin = new PostAdmin(
2593
            'sonata.post.admin.post',
2594
            'Application\Sonata\NewsBundle\Entity\Post',
2595
            'Sonata\NewsBundle\Controller\PostAdminController'
2596
        );
2597
        $commentAdmin = new CommentAdmin(
2598
            'sonata.post.admin.comment',
2599
            'Application\Sonata\NewsBundle\Entity\Comment',
2600
            'Sonata\NewsBundle\Controller\CommentAdminController'
2601
        );
2602
        $commentVoteAdmin = new CommentVoteAdmin(
2603
            'sonata.post.admin.comment_vote',
2604
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2605
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2606
        );
2607
2608
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2609
        $this->assertSame($commentAdmin, $commentAdmin->getRootAncestor());
2610
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2611
2612
        $postAdmin->addChild($commentAdmin, 'post');
2613
2614
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2615
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2616
        $this->assertSame($commentVoteAdmin, $commentVoteAdmin->getRootAncestor());
2617
2618
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2619
2620
        $this->assertSame($postAdmin, $postAdmin->getRootAncestor());
2621
        $this->assertSame($postAdmin, $commentAdmin->getRootAncestor());
2622
        $this->assertSame($postAdmin, $commentVoteAdmin->getRootAncestor());
2623
    }
2624
2625
    public function testGetChildDepth(): void
2626
    {
2627
        $postAdmin = new PostAdmin(
2628
            'sonata.post.admin.post',
2629
            'Application\Sonata\NewsBundle\Entity\Post',
2630
            'Sonata\NewsBundle\Controller\PostAdminController'
2631
        );
2632
        $commentAdmin = new CommentAdmin(
2633
            'sonata.post.admin.comment',
2634
            'Application\Sonata\NewsBundle\Entity\Comment',
2635
            'Sonata\NewsBundle\Controller\CommentAdminController'
2636
        );
2637
        $commentVoteAdmin = new CommentVoteAdmin(
2638
            'sonata.post.admin.comment_vote',
2639
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2640
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2641
        );
2642
2643
        $this->assertSame(0, $postAdmin->getChildDepth());
2644
        $this->assertSame(0, $commentAdmin->getChildDepth());
2645
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2646
2647
        $postAdmin->addChild($commentAdmin, 'post');
2648
2649
        $this->assertSame(0, $postAdmin->getChildDepth());
2650
        $this->assertSame(1, $commentAdmin->getChildDepth());
2651
        $this->assertSame(0, $commentVoteAdmin->getChildDepth());
2652
2653
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2654
2655
        $this->assertSame(0, $postAdmin->getChildDepth());
2656
        $this->assertSame(1, $commentAdmin->getChildDepth());
2657
        $this->assertSame(2, $commentVoteAdmin->getChildDepth());
2658
    }
2659
2660
    public function testGetCurrentLeafChildAdmin(): void
2661
    {
2662
        $postAdmin = new PostAdmin(
2663
            'sonata.post.admin.post',
2664
            'Application\Sonata\NewsBundle\Entity\Post',
2665
            'Sonata\NewsBundle\Controller\PostAdminController'
2666
        );
2667
        $commentAdmin = new CommentAdmin(
2668
            'sonata.post.admin.comment',
2669
            'Application\Sonata\NewsBundle\Entity\Comment',
2670
            'Sonata\NewsBundle\Controller\CommentAdminController'
2671
        );
2672
        $commentVoteAdmin = new CommentVoteAdmin(
2673
            'sonata.post.admin.comment_vote',
2674
            'Application\Sonata\NewsBundle\Entity\CommentVote',
2675
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
2676
        );
2677
2678
        $postAdmin->addChild($commentAdmin, 'post');
2679
        $commentAdmin->addChild($commentVoteAdmin, 'comment');
2680
2681
        $this->assertNull($postAdmin->getCurrentLeafChildAdmin());
2682
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2683
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2684
2685
        $commentAdmin->setCurrentChild(true);
2686
2687
        $this->assertSame($commentAdmin, $postAdmin->getCurrentLeafChildAdmin());
2688
        $this->assertNull($commentAdmin->getCurrentLeafChildAdmin());
2689
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2690
2691
        $commentVoteAdmin->setCurrentChild(true);
2692
2693
        $this->assertSame($commentVoteAdmin, $postAdmin->getCurrentLeafChildAdmin());
2694
        $this->assertSame($commentVoteAdmin, $commentAdmin->getCurrentLeafChildAdmin());
2695
        $this->assertNull($commentVoteAdmin->getCurrentLeafChildAdmin());
2696
    }
2697
2698
    public function testAdminWithoutControllerName(): void
2699
    {
2700
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', null);
2701
2702
        $this->assertNull($admin->getBaseControllerName());
2703
    }
2704
2705
    public function testAdminAvoidInifiniteLoop(): void
2706
    {
2707
        $this->expectNotToPerformAssertions();
2708
2709
        $formFactory = new FormFactory(new FormRegistry([], new ResolvedFormTypeFactory()));
2710
2711
        $admin = new AvoidInfiniteLoopAdmin('code', \stdClass::class, null);
2712
        $admin->setSubject(new \stdClass());
2713
2714
        $admin->setFormContractor(new FormContractor($formFactory));
2715
2716
        $admin->setShowBuilder(new ShowBuilder());
2717
2718
        $admin->setListBuilder(new ListBuilder());
2719
2720
        $pager = $this->createStub(PagerInterface::class);
2721
        $admin->setDatagridBuilder(new DatagridBuilder($formFactory, $pager));
2722
2723
        $validator = $this->createMock(ValidatorInterface::class);
2724
        $validator->method('getMetadataFor')->willReturn($this->createStub(MemberMetadata::class));
2725
        $admin->setValidator($validator);
2726
2727
        $routeGenerator = $this->createStub(RouteGeneratorInterface::class);
2728
        $admin->setRouteGenerator($routeGenerator);
2729
2730
        $admin->getForm();
2731
        $admin->getShow();
2732
        $admin->getList();
2733
        $admin->getDatagrid();
2734
    }
2735
2736
    /**
2737
     * NEXT_MAJOR: Remove this test and its data provider.
2738
     *
2739
     * @group legacy
2740
     *
2741
     * @dataProvider getDeprecatedAbstractAdminConstructorArgs
2742
     *
2743
     * @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.
2744
     */
2745
    public function testDeprecatedAbstractAdminConstructorArgs($code, $class, $baseControllerName): void
2746
    {
2747
        new PostAdmin($code, $class, $baseControllerName);
2748
    }
2749
2750
    public function getDeprecatedAbstractAdminConstructorArgs(): iterable
2751
    {
2752
        yield from [
2753
            ['sonata.post.admin.post', null, null],
2754
            [null, null, null],
2755
            ['sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', false],
2756
            ['sonata.post.admin.post', false, false],
2757
            [false, false, false],
2758
            [true, true, true],
2759
            [new \stdClass(), new \stdClass(), new \stdClass()],
2760
            [0, 0, 0],
2761
            [1, 1, 1],
2762
        ];
2763
    }
2764
}
2765