Completed
Pull Request — 3.x (#6311)
by Vincent
04:23
created

AdminTest::testGetBaseRoutePattern()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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
702
    /**
703
     * NEXT_MAJOR: Remove this test.
704
     *
705
     * @group legacy
706
     * @expectedDeprecation Passing boolean as argument 1 for Sonata\AdminBundle\Admin\AbstractAdmin::toString() is deprecated since sonata-project/admin-bundle 3.x. Only object will be allowed in version 4.0.
707
     */
708
    public function testToStringForNonObject(): void
709
    {
710
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
711
        $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...
712
    }
713
714
    public function testIsAclEnabled(): void
715
    {
716
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
717
718
        $this->assertFalse($postAdmin->isAclEnabled());
719
720
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
721
        $commentAdmin->setSecurityHandler($this->createMock(AclSecurityHandlerInterface::class));
722
        $this->assertTrue($commentAdmin->isAclEnabled());
723
    }
724
725
    /**
726
     * @group legacy
727
     *
728
     * @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.
729
     *
730
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClasses
731
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getSubClass
732
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::setSubClasses
733
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasSubClass
734
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
735
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubClass
736
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getActiveSubclassCode
737
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::getClass
738
     */
739
    public function testSubClass(): void
740
    {
741
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
742
        $admin = new PostAdmin(
743
            'sonata.post.admin.post',
744
            Post::class,
745
            'Sonata\NewsBundle\Controller\PostAdminController'
746
        );
747
        $this->assertFalse($admin->hasSubClass('test'));
748
        $this->assertFalse($admin->hasActiveSubClass());
749
        $this->assertCount(0, $admin->getSubClasses());
750
        $this->assertNull($admin->getActiveSubClass());
751
        $this->assertNull($admin->getActiveSubclassCode());
752
        $this->assertSame(Post::class, $admin->getClass());
753
754
        // Just for the record, if there is no inheritance set, the getSubject is not used
755
        // the getSubject can also lead to some issue
756
        $admin->setSubject(new BlogPost());
757
        $this->assertSame(BlogPost::class, $admin->getClass());
758
759
        $admin->setSubClasses([
760
            'extended1' => 'NewsBundle\Entity\PostExtended1',
761
            'extended2' => 'NewsBundle\Entity\PostExtended2',
762
        ]);
763
        $this->assertFalse($admin->hasSubClass('test'));
764
        $this->assertTrue($admin->hasSubClass('extended1'));
765
        $this->assertFalse($admin->hasActiveSubClass());
766
        $this->assertCount(2, $admin->getSubClasses());
767
        // NEXT_MAJOR: remove the following 2 `assertNull()` assertions
768
        $this->assertNull($admin->getActiveSubClass());
769
        $this->assertNull($admin->getActiveSubclassCode());
770
        $this->assertSame(
771
            BlogPost::class,
772
            $admin->getClass(),
773
            'When there is no subclass in the query the class parameter should be returned'
774
        );
775
776
        $request = new Request(['subclass' => 'extended1']);
777
        $admin->setRequest($request);
778
        $this->assertFalse($admin->hasSubClass('test'));
779
        $this->assertTrue($admin->hasSubClass('extended1'));
780
        $this->assertTrue($admin->hasActiveSubClass());
781
        $this->assertCount(2, $admin->getSubClasses());
782
        $this->assertSame(
783
            'NewsBundle\Entity\PostExtended1',
784
            $admin->getActiveSubClass(),
785
            'It should return the curently active sub class.'
786
        );
787
        $this->assertSame('extended1', $admin->getActiveSubclassCode());
788
        $this->assertSame(
789
            'NewsBundle\Entity\PostExtended1',
790
            $admin->getClass(),
791
            'getClass() should return the name of the sub class when passed through a request query parameter.'
792
        );
793
794
        $request->query->set('subclass', 'inject');
795
796
        $this->assertNull($admin->getActiveSubclassCode());
797
        // NEXT_MAJOR: remove the previous `assertNull()` assertion and uncomment the following lines
798
        // $this->expectException(\LogicException::class);
799
        // $this->expectExceptionMessage(sprintf('Admin "%s" has no active subclass.', PostAdmin::class));
800
    }
801
802
    /**
803
     * @group legacy
804
     *
805
     * @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.
806
     */
807
    public function testNonExistantSubclass(): void
808
    {
809
        // NEXT_MAJOR: Remove the "@group" and "@expectedDeprecation" annotations
810
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
811
        $admin->setModelManager($this->getMockForAbstractClass(ModelManagerInterface::class));
812
813
        $admin->setRequest(new Request(['subclass' => 'inject']));
814
815
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1', 'extended2' => 'NewsBundle\Entity\PostExtended2']);
816
817
        $this->assertTrue($admin->hasActiveSubClass());
818
819
        $this->expectException(\RuntimeException::class);
820
821
        $admin->getActiveSubClass();
822
    }
823
824
    /**
825
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::hasActiveSubClass
826
     */
827
    public function testOnlyOneSubclassNeededToBeActive(): void
828
    {
829
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
830
        $admin->setSubClasses(['extended1' => 'NewsBundle\Entity\PostExtended1']);
831
        $request = new Request(['subclass' => 'extended1']);
832
        $admin->setRequest($request);
833
        $this->assertTrue($admin->hasActiveSubClass());
834
    }
835
836
    /**
837
     * @group legacy
838
     * @expectedDeprecation Method "Sonata\AdminBundle\Admin\AbstractAdmin::addSubClass" is deprecated since sonata-project/admin-bundle 3.30 and will be removed in 4.0.
839
     */
840
    public function testAddSubClassIsDeprecated(): void
841
    {
842
        $admin = new PostAdmin(
843
            'sonata.post.admin.post',
844
            Post::class,
845
            'Sonata\NewsBundle\Controller\PostAdminController'
846
        );
847
        $admin->addSubClass('whatever');
848
    }
849
850
    /**
851
     * @group legacy
852
     */
853
    public function testGetPerPageOptions(): void
854
    {
855
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
856
857
        $perPageOptions = $admin->getPerPageOptions();
858
859
        foreach ($perPageOptions as $perPage) {
860
            $this->assertSame(0, $perPage % 4);
861
        }
862
863
        $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...
864
        $this->assertSame([500, 1000], $admin->getPerPageOptions());
865
    }
866
867
    public function testGetLabelTranslatorStrategy(): void
868
    {
869
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
870
871
        $this->assertNull($admin->getLabelTranslatorStrategy());
872
873
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
874
        $admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
875
        $this->assertSame($labelTranslatorStrategy, $admin->getLabelTranslatorStrategy());
876
    }
877
878
    public function testGetRouteBuilder(): void
879
    {
880
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
881
882
        $this->assertNull($admin->getRouteBuilder());
883
884
        $routeBuilder = $this->createMock(RouteBuilderInterface::class);
885
        $admin->setRouteBuilder($routeBuilder);
886
        $this->assertSame($routeBuilder, $admin->getRouteBuilder());
887
    }
888
889
    public function testGetMenuFactory(): void
890
    {
891
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
892
893
        $this->assertNull($admin->getMenuFactory());
894
895
        $menuFactory = $this->createMock(FactoryInterface::class);
896
        $admin->setMenuFactory($menuFactory);
897
        $this->assertSame($menuFactory, $admin->getMenuFactory());
898
    }
899
900
    public function testGetExtensions(): void
901
    {
902
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
903
904
        $this->assertSame([], $admin->getExtensions());
905
906
        $adminExtension1 = $this->createMock(AdminExtensionInterface::class);
907
        $adminExtension2 = $this->createMock(AdminExtensionInterface::class);
908
909
        $admin->addExtension($adminExtension1);
910
        $admin->addExtension($adminExtension2);
911
        $this->assertSame([$adminExtension1, $adminExtension2], $admin->getExtensions());
912
    }
913
914
    public function testGetFilterTheme(): void
915
    {
916
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
917
918
        $this->assertSame([], $admin->getFilterTheme());
919
920
        $admin->setFilterTheme(['FooTheme']);
921
        $this->assertSame(['FooTheme'], $admin->getFilterTheme());
922
    }
923
924
    public function testGetFormTheme(): void
925
    {
926
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
927
928
        $this->assertSame([], $admin->getFormTheme());
929
930
        $admin->setFormTheme(['FooTheme']);
931
932
        $this->assertSame(['FooTheme'], $admin->getFormTheme());
933
    }
934
935
    public function testGetValidator(): void
936
    {
937
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
938
939
        $this->assertNull($admin->getValidator());
940
941
        $validator = $this->getMockForAbstractClass(ValidatorInterface::class);
942
943
        $admin->setValidator($validator);
944
        $this->assertSame($validator, $admin->getValidator());
945
    }
946
947
    public function testGetSecurityHandler(): void
948
    {
949
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
950
951
        $this->assertNull($admin->getSecurityHandler());
952
953
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
954
        $admin->setSecurityHandler($securityHandler);
955
        $this->assertSame($securityHandler, $admin->getSecurityHandler());
956
    }
957
958
    public function testGetSecurityInformation(): void
959
    {
960
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
961
962
        $this->assertSame([], $admin->getSecurityInformation());
963
964
        $securityInformation = [
965
            'GUEST' => ['VIEW', 'LIST'],
966
            'STAFF' => ['EDIT', 'LIST', 'CREATE'],
967
        ];
968
969
        $admin->setSecurityInformation($securityInformation);
970
        $this->assertSame($securityInformation, $admin->getSecurityInformation());
971
    }
972
973
    public function testGetManagerType(): void
974
    {
975
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
976
977
        $this->assertNull($admin->getManagerType());
978
979
        $admin->setManagerType('foo_orm');
980
        $this->assertSame('foo_orm', $admin->getManagerType());
981
    }
982
983
    public function testGetModelManager(): void
984
    {
985
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
986
987
        $this->assertNull($admin->getModelManager());
988
989
        $modelManager = $this->createMock(ModelManagerInterface::class);
990
991
        $admin->setModelManager($modelManager);
992
        $this->assertSame($modelManager, $admin->getModelManager());
993
    }
994
995
    /**
996
     * NEXT_MAJOR: remove this method.
997
     *
998
     * @group legacy
999
     */
1000
    public function testGetBaseCodeRoute(): void
1001
    {
1002
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1003
1004
        $this->assertSame('', $admin->getBaseCodeRoute());
1005
1006
        $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...
1007
        $this->assertSame('foo', $admin->getBaseCodeRoute());
1008
    }
1009
1010
    // NEXT_MAJOR: uncomment this method.
1011
    // public function testGetBaseCodeRoute()
1012
    // {
1013
    //     $postAdmin = new PostAdmin(
1014
    //         'sonata.post.admin.post',
1015
    //         'NewsBundle\Entity\Post',
1016
    //         'Sonata\NewsBundle\Controller\PostAdminController'
1017
    //     );
1018
    //     $commentAdmin = new CommentAdmin(
1019
    //         'sonata.post.admin.comment',
1020
    //         'Application\Sonata\NewsBundle\Entity\Comment',
1021
    //         'Sonata\NewsBundle\Controller\CommentAdminController'
1022
    //     );
1023
    //
1024
    //     $this->assertSame($postAdmin->getCode(), $postAdmin->getBaseCodeRoute());
1025
    //
1026
    //     $postAdmin->addChild($commentAdmin);
1027
    //
1028
    //     $this->assertSame(
1029
    //         'sonata.post.admin.post|sonata.post.admin.comment',
1030
    //         $commentAdmin->getBaseCodeRoute()
1031
    //     );
1032
    // }
1033
1034
    public function testGetRouteGenerator(): void
1035
    {
1036
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1037
1038
        $this->assertNull($admin->getRouteGenerator());
1039
1040
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
1041
1042
        $admin->setRouteGenerator($routeGenerator);
1043
        $this->assertSame($routeGenerator, $admin->getRouteGenerator());
1044
    }
1045
1046
    public function testGetConfigurationPool(): void
1047
    {
1048
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1049
1050
        $this->assertNull($admin->getConfigurationPool());
1051
1052
        $pool = $this->getMockBuilder(Pool::class)
1053
            ->disableOriginalConstructor()
1054
            ->getMock();
1055
1056
        $admin->setConfigurationPool($pool);
1057
        $this->assertSame($pool, $admin->getConfigurationPool());
1058
    }
1059
1060
    public function testGetShowBuilder(): void
1061
    {
1062
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1063
1064
        $this->assertNull($admin->getShowBuilder());
1065
1066
        $showBuilder = $this->createMock(ShowBuilderInterface::class);
1067
1068
        $admin->setShowBuilder($showBuilder);
1069
        $this->assertSame($showBuilder, $admin->getShowBuilder());
1070
    }
1071
1072
    public function testGetListBuilder(): void
1073
    {
1074
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1075
1076
        $this->assertNull($admin->getListBuilder());
1077
1078
        $listBuilder = $this->createMock(ListBuilderInterface::class);
1079
1080
        $admin->setListBuilder($listBuilder);
1081
        $this->assertSame($listBuilder, $admin->getListBuilder());
1082
    }
1083
1084
    public function testGetDatagridBuilder(): void
1085
    {
1086
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1087
1088
        $this->assertNull($admin->getDatagridBuilder());
1089
1090
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1091
1092
        $admin->setDatagridBuilder($datagridBuilder);
1093
        $this->assertSame($datagridBuilder, $admin->getDatagridBuilder());
1094
    }
1095
1096
    public function testGetFormContractor(): void
1097
    {
1098
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1099
1100
        $this->assertNull($admin->getFormContractor());
1101
1102
        $formContractor = $this->createMock(FormContractorInterface::class);
1103
1104
        $admin->setFormContractor($formContractor);
1105
        $this->assertSame($formContractor, $admin->getFormContractor());
1106
    }
1107
1108
    public function testGetRequest(): void
1109
    {
1110
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1111
1112
        $this->assertFalse($admin->hasRequest());
1113
1114
        $request = new Request();
1115
1116
        $admin->setRequest($request);
1117
        $this->assertSame($request, $admin->getRequest());
1118
        $this->assertTrue($admin->hasRequest());
1119
    }
1120
1121
    public function testGetRequestWithException(): void
1122
    {
1123
        $this->expectException(\RuntimeException::class);
1124
        $this->expectExceptionMessage('The Request object has not been set');
1125
1126
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1127
        $admin->getRequest();
1128
    }
1129
1130
    public function testGetTranslationDomain(): void
1131
    {
1132
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1133
1134
        $this->assertSame('messages', $admin->getTranslationDomain());
1135
1136
        $admin->setTranslationDomain('foo');
1137
        $this->assertSame('foo', $admin->getTranslationDomain());
1138
    }
1139
1140
    /**
1141
     * @group legacy
1142
     */
1143
    public function testGetTranslator(): void
1144
    {
1145
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1146
1147
        $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...
1148
1149
        $translator = $this->createMock(TranslatorInterface::class);
1150
1151
        $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...
1152
        $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...
1153
    }
1154
1155
    public function testGetShowGroups(): void
1156
    {
1157
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1158
1159
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1160
        $this->assertFalse($admin->getShowGroups('sonata_deprecation_mute'));
1161
1162
        $groups = ['foo', 'bar', 'baz'];
1163
1164
        $admin->setShowGroups($groups);
1165
        $this->assertSame($groups, $admin->getShowGroups());
1166
    }
1167
1168
    public function testGetFormGroups(): void
1169
    {
1170
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1171
1172
        // NEXT_MAJOR: Remove the argument "sonata_deprecation_mute" in the following call.
1173
        $this->assertFalse($admin->getFormGroups('sonata_deprecation_mute'));
1174
1175
        $groups = ['foo', 'bar', 'baz'];
1176
1177
        $admin->setFormGroups($groups);
1178
        $this->assertSame($groups, $admin->getFormGroups());
1179
    }
1180
1181
    public function testGetMaxPageLinks(): void
1182
    {
1183
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1184
1185
        $this->assertSame(25, $admin->getMaxPageLinks());
1186
1187
        $admin->setMaxPageLinks(14);
1188
        $this->assertSame(14, $admin->getMaxPageLinks());
1189
    }
1190
1191
    /**
1192
     * @group legacy
1193
     */
1194
    public function testGetMaxPerPage(): void
1195
    {
1196
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1197
1198
        $this->assertSame(32, $admin->getMaxPerPage());
1199
1200
        $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...
1201
        $this->assertSame(94, $admin->getMaxPerPage());
1202
    }
1203
1204
    public function testGetLabel(): void
1205
    {
1206
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1207
1208
        $this->assertNull($admin->getLabel());
1209
1210
        $admin->setLabel('FooLabel');
1211
        $this->assertSame('FooLabel', $admin->getLabel());
1212
    }
1213
1214
    public function testGetBaseController(): void
1215
    {
1216
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1217
1218
        $this->assertSame('Sonata\NewsBundle\Controller\PostAdminController', $admin->getBaseControllerName());
1219
1220
        $admin->setBaseControllerName('Sonata\NewsBundle\Controller\FooAdminController');
1221
        $this->assertSame('Sonata\NewsBundle\Controller\FooAdminController', $admin->getBaseControllerName());
1222
    }
1223
1224
    public function testGetTemplates(): void
1225
    {
1226
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1227
1228
        $templates = [
1229
            'list' => '@FooAdmin/CRUD/list.html.twig',
1230
            'show' => '@FooAdmin/CRUD/show.html.twig',
1231
            'edit' => '@FooAdmin/CRUD/edit.html.twig',
1232
        ];
1233
1234
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1235
        $templateRegistry->getTemplates()->shouldBeCalled()->willReturn($templates);
1236
1237
        $admin->setTemplateRegistry($templateRegistry->reveal());
1238
1239
        $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...
1240
    }
1241
1242
    public function testGetTemplate1(): void
1243
    {
1244
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1245
1246
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
1247
        $templateRegistry->getTemplate('edit')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/edit.html.twig');
1248
        $templateRegistry->getTemplate('show')->shouldBeCalled()->willReturn('@FooAdmin/CRUD/show.html.twig');
1249
1250
        $admin->setTemplateRegistry($templateRegistry->reveal());
1251
1252
        $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...
1253
        $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...
1254
    }
1255
1256
    public function testGetIdParameter(): void
1257
    {
1258
        $postAdmin = new PostAdmin(
1259
            'sonata.post.admin.post',
1260
            'NewsBundle\Entity\Post',
1261
            'Sonata\NewsBundle\Controller\PostAdminController'
1262
        );
1263
1264
        $this->assertSame('id', $postAdmin->getIdParameter());
1265
        $this->assertFalse($postAdmin->isChild());
1266
1267
        $commentAdmin = new CommentAdmin(
1268
            'sonata.post.admin.comment',
1269
            'Application\Sonata\NewsBundle\Entity\Comment',
1270
            'Sonata\NewsBundle\Controller\CommentAdminController'
1271
        );
1272
        $commentAdmin->setParent($postAdmin);
1273
1274
        $this->assertTrue($commentAdmin->isChild());
1275
        $this->assertSame('childId', $commentAdmin->getIdParameter());
1276
1277
        $commentVoteAdmin = new CommentVoteAdmin(
1278
            'sonata.post.admin.comment_vote',
1279
            'Application\Sonata\NewsBundle\Entity\CommentVote',
1280
            'Sonata\NewsBundle\Controller\CommentVoteAdminController'
1281
        );
1282
        $commentVoteAdmin->setParent($commentAdmin);
1283
1284
        $this->assertTrue($commentVoteAdmin->isChild());
1285
        $this->assertSame('childChildId', $commentVoteAdmin->getIdParameter());
1286
    }
1287
1288
    public function testGetExportFormats(): void
1289
    {
1290
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1291
1292
        $this->assertSame(['json', 'xml', 'csv', 'xls'], $admin->getExportFormats());
1293
    }
1294
1295
    public function testGetUrlsafeIdentifier(): void
1296
    {
1297
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1298
1299
        $model = new \stdClass();
1300
1301
        $modelManager = $this->createMock(ModelManagerInterface::class);
1302
        $modelManager->expects($this->once())
1303
            ->method('getUrlSafeIdentifier')
1304
            ->with($this->equalTo($model))
1305
            ->willReturn('foo');
1306
        $admin->setModelManager($modelManager);
1307
1308
        $this->assertSame('foo', $admin->getUrlSafeIdentifier($model));
1309
    }
1310
1311
    public function testDeterminedPerPageValue(): void
1312
    {
1313
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1314
1315
        $this->assertFalse($admin->determinedPerPageValue('foo'));
1316
        $this->assertFalse($admin->determinedPerPageValue(123));
1317
        $this->assertTrue($admin->determinedPerPageValue(16));
1318
    }
1319
1320
    public function testIsGranted(): void
1321
    {
1322
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1323
        $modelManager = $this->createStub(ModelManagerInterface::class);
1324
        $modelManager
1325
            ->method('getNormalizedIdentifier')
1326
            ->willReturnCallback(static function (?object $model = null): ?string {
1327
                return $model ? $model->id : null;
1328
            });
1329
1330
        $admin->setModelManager($modelManager);
1331
1332
        $entity1 = new \stdClass();
1333
        $entity1->id = '1';
1334
1335
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1336
        $securityHandler
1337
            ->expects($this->exactly(6))
1338
            ->method('isGranted')
1339
            ->willReturnCallback(static function (
1340
                AdminInterface $adminIn,
1341
                string $attributes,
1342
                ?object $object = null
1343
            ) use (
1344
                $admin,
1345
                $entity1
1346
            ): bool {
1347
                return $admin === $adminIn && 'FOO' === $attributes &&
1348
                    ($object === $admin || $object === $entity1);
1349
            });
1350
1351
        $admin->setSecurityHandler($securityHandler);
1352
1353
        $this->assertTrue($admin->isGranted('FOO'));
1354
        $this->assertTrue($admin->isGranted('FOO'));
1355
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1356
        $this->assertTrue($admin->isGranted('FOO', $entity1));
1357
        $this->assertFalse($admin->isGranted('BAR'));
1358
        $this->assertFalse($admin->isGranted('BAR'));
1359
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1360
        $this->assertFalse($admin->isGranted('BAR', $entity1));
1361
1362
        $entity2 = new \stdClass();
1363
        $entity2->id = '2';
1364
1365
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1366
        $this->assertFalse($admin->isGranted('BAR', $entity2));
1367
1368
        $entity3 = new \stdClass();
1369
        $entity3->id = '3';
1370
1371
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1372
        $this->assertFalse($admin->isGranted('BAR', $entity3));
1373
    }
1374
1375
    public function testSupportsPreviewMode(): void
1376
    {
1377
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1378
1379
        $this->assertFalse($admin->supportsPreviewMode());
1380
    }
1381
1382
    public function testGetPermissionsShow(): void
1383
    {
1384
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1385
1386
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_DASHBOARD));
1387
        $this->assertSame(['LIST'], $admin->getPermissionsShow(AbstractAdmin::CONTEXT_MENU));
1388
        $this->assertSame(['LIST'], $admin->getPermissionsShow('foo'));
1389
    }
1390
1391
    public function testShowIn(): void
1392
    {
1393
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1394
1395
        $securityHandler = $this->createMock(AclSecurityHandlerInterface::class);
1396
        $securityHandler
1397
            ->method('isGranted')
1398
            ->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...
1399
                return $admin === $adminIn && $attributes === ['LIST'];
1400
            });
1401
1402
        $admin->setSecurityHandler($securityHandler);
1403
1404
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD));
1405
        $this->assertTrue($admin->showIn(AbstractAdmin::CONTEXT_MENU));
1406
        $this->assertTrue($admin->showIn('foo'));
1407
    }
1408
1409
    public function testGetObjectIdentifier(): void
1410
    {
1411
        $admin = new PostAdmin('sonata.post.admin.post', 'Acme\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1412
1413
        $this->assertSame('sonata.post.admin.post', $admin->getObjectIdentifier());
1414
    }
1415
1416
    /**
1417
     * @group legacy
1418
     */
1419
    public function testTrans(): void
1420
    {
1421
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1422
        $admin->setTranslationDomain('fooMessageDomain');
1423
1424
        $translator = $this->createMock(TranslatorInterface::class);
1425
        $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...
1426
1427
        $translator->expects($this->once())
1428
            ->method('trans')
1429
            ->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1430
            ->willReturn('fooTranslated');
1431
1432
        $this->assertSame('fooTranslated', $admin->trans('foo'));
1433
    }
1434
1435
    /**
1436
     * @group legacy
1437
     */
1438
    public function testTransWithMessageDomain(): void
1439
    {
1440
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1441
1442
        $translator = $this->createMock(TranslatorInterface::class);
1443
        $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...
1444
1445
        $translator->expects($this->once())
1446
            ->method('trans')
1447
            ->with($this->equalTo('foo'), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1448
            ->willReturn('fooTranslated');
1449
1450
        $this->assertSame('fooTranslated', $admin->trans('foo', ['name' => 'Andrej'], 'fooMessageDomain'));
1451
    }
1452
1453
    /**
1454
     * @group legacy
1455
     */
1456
    public function testTransChoice(): void
1457
    {
1458
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1459
        $admin->setTranslationDomain('fooMessageDomain');
1460
1461
        $translator = $this->createMock(TranslatorInterface::class);
1462
        $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...
1463
1464
        $translator->expects($this->once())
1465
            ->method('transChoice')
1466
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo([]), $this->equalTo('fooMessageDomain'))
1467
            ->willReturn('fooTranslated');
1468
1469
        $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...
1470
    }
1471
1472
    /**
1473
     * @group legacy
1474
     */
1475
    public function testTransChoiceWithMessageDomain(): void
1476
    {
1477
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1478
1479
        $translator = $this->createMock(TranslatorInterface::class);
1480
        $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...
1481
1482
        $translator->expects($this->once())
1483
            ->method('transChoice')
1484
            ->with($this->equalTo('foo'), $this->equalTo(2), $this->equalTo(['name' => 'Andrej']), $this->equalTo('fooMessageDomain'))
1485
            ->willReturn('fooTranslated');
1486
1487
        $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...
1488
    }
1489
1490
    public function testSetFilterPersister(): void
1491
    {
1492
        $admin = new class('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'SonataNewsBundle\Controller\PostAdminController') extends PostAdmin {
1493
            public function persistFilters(): bool
1494
            {
1495
                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...
1496
            }
1497
        };
1498
1499
        $filterPersister = $this->createMock(FilterPersisterInterface::class);
1500
1501
        $admin->setFilterPersister($filterPersister);
1502
        $this->assertTrue($admin->persistFilters());
1503
    }
1504
1505
    public function testGetRootCode(): void
1506
    {
1507
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1508
1509
        $this->assertSame('sonata.post.admin.post', $admin->getRootCode());
1510
1511
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1512
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1513
        $parentFieldDescription->expects($this->once())
1514
            ->method('getAdmin')
1515
            ->willReturn($parentAdmin);
1516
1517
        $this->assertFalse($admin->hasParentFieldDescription());
1518
        $admin->setParentFieldDescription($parentFieldDescription);
1519
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1520
        $this->assertSame('sonata.post.admin.post.parent', $admin->getRootCode());
1521
    }
1522
1523
    public function testGetRoot(): void
1524
    {
1525
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1526
1527
        $this->assertSame($admin, $admin->getRoot());
1528
1529
        $parentAdmin = new PostAdmin('sonata.post.admin.post.parent', 'NewsBundle\Entity\PostParent', 'Sonata\NewsBundle\Controller\PostParentAdminController');
1530
        $parentFieldDescription = $this->createMock(FieldDescriptionInterface::class);
1531
        $parentFieldDescription->expects($this->once())
1532
            ->method('getAdmin')
1533
            ->willReturn($parentAdmin);
1534
1535
        $this->assertFalse($admin->hasParentFieldDescription());
1536
        $admin->setParentFieldDescription($parentFieldDescription);
1537
        $this->assertSame($parentFieldDescription, $admin->getParentFieldDescription());
1538
        $this->assertSame($parentAdmin, $admin->getRoot());
1539
    }
1540
1541
    public function testGetExportFields(): void
1542
    {
1543
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1544
1545
        $modelManager = $this->createMock(ModelManagerInterface::class);
1546
        $modelManager->expects($this->once())
1547
            ->method('getExportFields')
1548
            ->with($this->equalTo('NewsBundle\Entity\Post'))
1549
            ->willReturn(['foo', 'bar']);
1550
1551
        $admin->setModelManager($modelManager);
1552
        $this->assertSame(['foo', 'bar'], $admin->getExportFields());
1553
    }
1554
1555
    public function testGetPersistentParametersWithNoExtension(): void
1556
    {
1557
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1558
1559
        $this->assertEmpty($admin->getPersistentParameters());
1560
    }
1561
1562
    public function testGetPersistentParametersWithInvalidExtension(): void
1563
    {
1564
        $this->expectException(\RuntimeException::class);
1565
1566
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1567
1568
        $extension = $this->createMock(AdminExtensionInterface::class);
1569
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn(null);
1570
1571
        $admin->addExtension($extension);
1572
1573
        $admin->getPersistentParameters();
1574
    }
1575
1576
    public function testGetPersistentParametersWithValidExtension(): void
1577
    {
1578
        $expected = [
1579
            'context' => 'foobar',
1580
        ];
1581
1582
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1583
1584
        $extension = $this->createMock(AdminExtensionInterface::class);
1585
        $extension->expects($this->once())->method('getPersistentParameters')->willReturn($expected);
1586
1587
        $admin->addExtension($extension);
1588
1589
        $this->assertSame($expected, $admin->getPersistentParameters());
1590
    }
1591
1592
    public function testGetNewInstanceForChildAdminWithParentValue(): void
1593
    {
1594
        $post = new Post();
1595
1596
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1597
        $postAdmin->method('getObject')->willReturn($post);
1598
1599
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1600
        $formBuilder->method('getForm')->willReturn(null);
1601
1602
        $tag = new Tag();
1603
1604
        $modelManager = $this->createStub(ModelManagerInterface::class);
1605
        $modelManager->method('getModelInstance')->willReturn($tag);
1606
1607
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1608
        $tagAdmin->setModelManager($modelManager);
1609
        $tagAdmin->setParent($postAdmin);
1610
1611
        $request = $this->createStub(Request::class);
1612
        $tagAdmin->setRequest($request);
1613
1614
        $configurationPool = $this->getMockBuilder(Pool::class)
1615
            ->disableOriginalConstructor()
1616
            ->getMock();
1617
1618
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1619
1620
        $tagAdmin->setConfigurationPool($configurationPool);
1621
1622
        $tag = $tagAdmin->getNewInstance();
1623
1624
        $this->assertSame($post, $tag->getPost());
1625
    }
1626
1627
    public function testGetNewInstanceForChildAdminWithCollectionParentValue(): void
1628
    {
1629
        $post = new Post();
1630
1631
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1632
        $postAdmin->method('getObject')->willReturn($post);
1633
1634
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1635
        $formBuilder->method('getForm')->willReturn(null);
1636
1637
        $postCategory = new PostCategory();
1638
1639
        $modelManager = $this->createStub(ModelManagerInterface::class);
1640
        $modelManager->method('getModelInstance')->willReturn($postCategory);
1641
1642
        $postCategoryAdmin = new PostCategoryAdmin('admin.post_category', PostCategoryAdmin::class, 'MyBundle\MyController');
1643
        $postCategoryAdmin->setModelManager($modelManager);
1644
        $postCategoryAdmin->setParent($postAdmin);
1645
1646
        $request = $this->createStub(Request::class);
1647
        $postCategoryAdmin->setRequest($request);
1648
1649
        $configurationPool = $this->getMockBuilder(Pool::class)
1650
            ->disableOriginalConstructor()
1651
            ->getMock();
1652
1653
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1654
1655
        $postCategoryAdmin->setConfigurationPool($configurationPool);
1656
1657
        $postCategory = $postCategoryAdmin->getNewInstance();
1658
1659
        $this->assertInstanceOf(Collection::class, $postCategory->getPosts());
1660
        $this->assertCount(1, $postCategory->getPosts());
1661
        $this->assertContains($post, $postCategory->getPosts());
1662
    }
1663
1664
    public function testGetNewInstanceForEmbededAdminWithParentValue(): void
1665
    {
1666
        $post = new Post();
1667
1668
        $postAdmin = $this->getMockBuilder(PostAdmin::class)->disableOriginalConstructor()->getMock();
1669
        $postAdmin->method('getObject')->willReturn($post);
1670
1671
        $formBuilder = $this->createStub(FormBuilderInterface::class);
1672
        $formBuilder->method('getForm')->willReturn(null);
1673
1674
        $parentField = $this->createStub(FieldDescriptionInterface::class);
1675
        $parentField->method('getAdmin')->willReturn($postAdmin);
1676
        $parentField->method('getParentAssociationMappings')->willReturn([]);
1677
        $parentField->method('getAssociationMapping')->willReturn(['fieldName' => 'tag', 'mappedBy' => 'post']);
1678
1679
        $tag = new Tag();
1680
1681
        $modelManager = $this->createStub(ModelManagerInterface::class);
1682
        $modelManager->method('getModelInstance')->willReturn($tag);
1683
1684
        $tagAdmin = new TagAdmin('admin.tag', Tag::class, 'MyBundle\MyController');
1685
        $tagAdmin->setModelManager($modelManager);
1686
        $tagAdmin->setParentFieldDescription($parentField);
1687
1688
        $request = $this->createStub(Request::class);
1689
        $tagAdmin->setRequest($request);
1690
1691
        $configurationPool = $this->getMockBuilder(Pool::class)
1692
            ->disableOriginalConstructor()
1693
            ->getMock();
1694
1695
        $configurationPool->method('getPropertyAccessor')->willReturn(PropertyAccess::createPropertyAccessor());
1696
1697
        $tagAdmin->setConfigurationPool($configurationPool);
1698
1699
        $tag = $tagAdmin->getNewInstance();
1700
1701
        $this->assertSame($post, $tag->getPost());
1702
    }
1703
1704
    public function testFormAddPostSubmitEventForPreValidation(): void
1705
    {
1706
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1707
        $object = new \stdClass();
1708
1709
        $labelTranslatorStrategy = $this->createMock(LabelTranslatorStrategyInterface::class);
1710
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1711
1712
        $validator = $this->createMock(ValidatorInterface::class);
1713
        $validator
1714
                ->method('getMetadataFor')
1715
                ->willReturn($this->createMock(MemberMetadata::class));
1716
        $modelAdmin->setValidator($validator);
1717
1718
        $modelManager = $this->createMock(ModelManagerInterface::class);
1719
        $modelManager
1720
            ->method('getNewFieldDescriptionInstance')
1721
            ->willReturn(new FieldDescription());
1722
        $modelAdmin->setModelManager($modelManager);
1723
1724
        // a Admin class to test that preValidate is called
1725
        $testAdminPreValidate = $this->createMock(AbstractAdmin::class);
1726
        $testAdminPreValidate->expects($this->once())
1727
                ->method('preValidate')
1728
                ->with($this->identicalTo($object));
1729
1730
        $event = $this->createMock(FormEvent::class);
1731
        $event
1732
                ->method('getData')
1733
                ->willReturn($object);
1734
1735
        $formBuild = $this->createMock(FormBuilder::class);
1736
        $formBuild->expects($this->once())
1737
                ->method('addEventListener')
1738
                ->with(
1739
                    $this->identicalTo(FormEvents::POST_SUBMIT),
1740
                    $this->callback(static function ($callback) use ($testAdminPreValidate, $event): bool {
1741
                        if (\is_callable($callback)) {
1742
                            $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...
1743
                            $closure($event);
1744
1745
                            return true;
1746
                        }
1747
1748
                        return false;
1749
                    }),
1750
                    $this->greaterThan(0)
1751
                );
1752
1753
        $form = $this->createMock(FormInterface::class);
1754
        $formBuild->expects($this->once())
1755
            ->method('getForm')
1756
            ->willReturn($form)
1757
        ;
1758
1759
        $formContractor = $this->createMock(FormContractorInterface::class);
1760
        $formContractor
1761
                ->method('getDefaultOptions')
1762
                ->willReturn([]);
1763
        $formContractor
1764
                ->method('getFormBuilder')
1765
                ->willReturn($formBuild);
1766
1767
        $modelAdmin->setFormContractor($formContractor);
1768
        $modelAdmin->setSubject($object);
1769
        $modelAdmin->defineFormBuilder($formBuild);
1770
        $modelAdmin->getForm();
1771
    }
1772
1773
    public function testCanAddInlineValidationOnlyForGenericMetadata(): void
1774
    {
1775
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', \stdClass::class, 'Sonata\FooBundle\Controller\ModelAdminController');
1776
        $object = new \stdClass();
1777
1778
        $labelTranslatorStrategy = $this->createStub(LabelTranslatorStrategyInterface::class);
1779
        $modelAdmin->setLabelTranslatorStrategy($labelTranslatorStrategy);
1780
1781
        $validator = $this->createStub(ValidatorInterface::class);
1782
        $metadata = $this->createStub(PropertyMetadataInterface::class);
1783
        $validator
1784
            ->method('getMetadataFor')
1785
            ->willReturn($metadata);
1786
        $modelAdmin->setValidator($validator);
1787
1788
        $modelManager = $this->createStub(ModelManagerInterface::class);
1789
        $modelManager
1790
            ->method('getNewFieldDescriptionInstance')
1791
            ->willReturn(new FieldDescription());
1792
        $modelAdmin->setModelManager($modelManager);
1793
1794
        $event = $this->createStub(FormEvent::class);
1795
        $event
1796
            ->method('getData')
1797
            ->willReturn($object);
1798
1799
        $formBuild = $this->createStub(FormBuilder::class);
1800
1801
        $formContractor = $this->createStub(FormContractorInterface::class);
1802
        $formContractor
1803
            ->method('getDefaultOptions')
1804
            ->willReturn([]);
1805
        $formContractor
1806
            ->method('getFormBuilder')
1807
            ->willReturn($formBuild);
1808
1809
        $modelAdmin->setFormContractor($formContractor);
1810
        $modelAdmin->setSubject($object);
1811
1812
        $this->expectException(\RuntimeException::class);
1813
        $this->expectExceptionMessage(
1814
            sprintf(
1815
                'Cannot add inline validator for stdClass because its metadata is an instance of %s instead of Symfony\Component\Validator\Mapping\GenericMetadata',
1816
                \get_class($metadata)
1817
            )
1818
        );
1819
1820
        $modelAdmin->defineFormBuilder($formBuild);
1821
    }
1822
1823
    public function testRemoveFieldFromFormGroup(): void
1824
    {
1825
        $formGroups = [
1826
            'foobar' => [
1827
                'fields' => [
1828
                    'foo' => 'foo',
1829
                    'bar' => 'bar',
1830
                ],
1831
            ],
1832
        ];
1833
1834
        $admin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1835
        $admin->setFormGroups($formGroups);
1836
1837
        $admin->removeFieldFromFormGroup('foo');
1838
        $this->assertSame($admin->getFormGroups(), [
1839
            'foobar' => [
1840
                'fields' => [
1841
                    'bar' => 'bar',
1842
                ],
1843
            ],
1844
        ]);
1845
1846
        $admin->removeFieldFromFormGroup('bar');
1847
        $this->assertSame($admin->getFormGroups(), []);
1848
    }
1849
1850
    public function testGetFilterParameters(): void
1851
    {
1852
        $authorId = uniqid();
1853
1854
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1855
1856
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
1857
        $commentAdmin->setParentAssociationMapping('post.author');
1858
        $commentAdmin->setParent($postAdmin);
1859
1860
        $request = $this->createMock(Request::class);
1861
        $query = $this->createMock(ParameterBag::class);
1862
        $query
1863
            ->method('get')
1864
            ->willReturn([
1865
                'filter' => [
1866
                    '_page' => '1',
1867
                    '_per_page' => '32',
1868
                ],
1869
            ]);
1870
1871
        $request->query = $query;
1872
        $request
1873
            ->method('get')
1874
            ->willReturn($authorId);
1875
1876
        $commentAdmin->setRequest($request);
1877
1878
        $modelManager = $this->createMock(ModelManagerInterface::class);
1879
        $modelManager
1880
            ->method('getDefaultSortValues')
1881
            ->willReturn([]);
1882
1883
        $commentAdmin->setModelManager($modelManager);
1884
1885
        $parameters = $commentAdmin->getFilterParameters();
1886
1887
        $this->assertTrue(isset($parameters['post__author']));
1888
        $this->assertSame(['value' => $authorId], $parameters['post__author']);
1889
    }
1890
1891
    public function testGetFilterFieldDescription(): void
1892
    {
1893
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1894
1895
        $fooFieldDescription = new FieldDescription();
1896
        $barFieldDescription = new FieldDescription();
1897
        $bazFieldDescription = new FieldDescription();
1898
1899
        $modelManager = $this->createMock(ModelManagerInterface::class);
1900
        $modelManager->expects($this->exactly(3))
1901
            ->method('getNewFieldDescriptionInstance')
1902
            ->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...
1903
                switch ($name) {
1904
                    case 'foo':
1905
                        $fieldDescription = $fooFieldDescription;
1906
1907
                        break;
1908
1909
                    case 'bar':
1910
                        $fieldDescription = $barFieldDescription;
1911
1912
                        break;
1913
1914
                    case 'baz':
1915
                        $fieldDescription = $bazFieldDescription;
1916
1917
                        break;
1918
1919
                    default:
1920
                        throw new \RuntimeException(sprintf('Unknown filter name "%s"', $name));
1921
                        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...
1922
                }
1923
1924
                $fieldDescription->setName($name);
1925
1926
                return $fieldDescription;
1927
            });
1928
1929
        $modelAdmin->setModelManager($modelManager);
1930
1931
        $pager = $this->createMock(PagerInterface::class);
1932
1933
        $datagrid = $this->createMock(DatagridInterface::class);
1934
        $datagrid->expects($this->once())
1935
            ->method('getPager')
1936
            ->willReturn($pager);
1937
1938
        $datagridBuilder = $this->createMock(DatagridBuilderInterface::class);
1939
        $datagridBuilder->expects($this->once())
1940
            ->method('getBaseDatagrid')
1941
            ->with($this->identicalTo($modelAdmin), [])
1942
            ->willReturn($datagrid);
1943
1944
        $datagridBuilder->expects($this->exactly(3))
1945
            ->method('addFilter')
1946
            ->willReturnCallback(static function ($datagrid, $type, $fieldDescription, AdminInterface $admin): void {
1947
                $admin->addFilterFieldDescription($fieldDescription->getName(), $fieldDescription);
1948
                $fieldDescription->mergeOption('field_options', ['required' => false]);
1949
            });
1950
1951
        $modelAdmin->setDatagridBuilder($datagridBuilder);
1952
1953
        $this->assertSame(['foo' => $fooFieldDescription, 'bar' => $barFieldDescription, 'baz' => $bazFieldDescription], $modelAdmin->getFilterFieldDescriptions());
1954
        $this->assertFalse($modelAdmin->hasFilterFieldDescription('fooBar'));
1955
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('foo'));
1956
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('bar'));
1957
        $this->assertTrue($modelAdmin->hasFilterFieldDescription('baz'));
1958
        $this->assertSame($fooFieldDescription, $modelAdmin->getFilterFieldDescription('foo'));
1959
        $this->assertSame($barFieldDescription, $modelAdmin->getFilterFieldDescription('bar'));
1960
        $this->assertSame($bazFieldDescription, $modelAdmin->getFilterFieldDescription('baz'));
1961
    }
1962
1963
    public function testGetSubjectNoRequest(): void
1964
    {
1965
        $modelManager = $this->createMock(ModelManagerInterface::class);
1966
        $modelManager
1967
            ->expects($this->never())
1968
            ->method('find');
1969
1970
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
1971
        $admin->setModelManager($modelManager);
1972
1973
        $this->assertFalse($admin->hasSubject());
1974
    }
1975
1976
    public function testGetSideMenu(): void
1977
    {
1978
        $item = $this->createMock(ItemInterface::class);
1979
        $item
1980
            ->expects($this->once())
1981
            ->method('setChildrenAttribute')
1982
            ->with('class', 'nav navbar-nav');
1983
        $item
1984
            ->expects($this->once())
1985
            ->method('setExtra')
1986
            ->with('translation_domain', 'foo_bar_baz');
1987
1988
        $menuFactory = $this->createMock(FactoryInterface::class);
1989
        $menuFactory
1990
            ->expects($this->once())
1991
            ->method('createItem')
1992
            ->willReturn($item);
1993
1994
        $modelAdmin = new ModelAdmin('sonata.post.admin.model', 'Application\Sonata\FooBundle\Entity\Model', 'Sonata\FooBundle\Controller\ModelAdminController');
1995
        $modelAdmin->setMenuFactory($menuFactory);
1996
        $modelAdmin->setTranslationDomain('foo_bar_baz');
1997
1998
        $modelAdmin->getSideMenu('foo');
1999
    }
2000
2001
    /**
2002
     * @return array
2003
     */
2004
    public function provideGetSubject()
2005
    {
2006
        return [
2007
            [23],
2008
            ['azerty'],
2009
            ['4f69bbb5f14a13347f000092'],
2010
            ['0779ca8d-e2be-11e4-ac58-0242ac11000b'],
2011
            [sprintf('123%smy_type', AdapterInterface::ID_SEPARATOR)], // composite keys are supported
2012
        ];
2013
    }
2014
2015
    /**
2016
     * @dataProvider provideGetSubject
2017
     */
2018
    public function testGetSubjectFailed($id): void
2019
    {
2020
        $modelManager = $this->createMock(ModelManagerInterface::class);
2021
        $modelManager
2022
            ->expects($this->once())
2023
            ->method('find')
2024
            ->with('NewsBundle\Entity\Post', $id)
2025
            ->willReturn(null); // entity not found
2026
2027
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2028
        $admin->setModelManager($modelManager);
2029
2030
        $admin->setRequest(new Request(['id' => $id]));
2031
        $this->assertFalse($admin->hasSubject());
2032
    }
2033
2034
    /**
2035
     * @dataProvider provideGetSubject
2036
     */
2037
    public function testGetSubject($id): void
2038
    {
2039
        $model = new Post();
2040
2041
        $modelManager = $this->createMock(ModelManagerInterface::class);
2042
        $modelManager
2043
            ->expects($this->once())
2044
            ->method('find')
2045
            ->with('NewsBundle\Entity\Post', $id)
2046
            ->willReturn($model);
2047
2048
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2049
        $admin->setModelManager($modelManager);
2050
2051
        $admin->setRequest(new Request(['id' => $id]));
2052
        $this->assertTrue($admin->hasSubject());
2053
        $this->assertSame($model, $admin->getSubject());
2054
        $this->assertSame($model, $admin->getSubject()); // model manager must be used only once
2055
    }
2056
2057
    public function testGetSubjectWithParentDescription(): void
2058
    {
2059
        $adminId = 1;
2060
2061
        $comment = new Comment();
2062
2063
        $modelManager = $this->createMock(ModelManagerInterface::class);
2064
        $modelManager
2065
            ->method('find')
2066
            ->with('NewsBundle\Entity\Comment', $adminId)
2067
            ->willReturn($comment);
2068
2069
        $request = new Request(['id' => $adminId]);
2070
2071
        $postAdmin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2072
        $postAdmin->setRequest($request);
2073
2074
        $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'NewsBundle\Entity\Comment', 'Sonata\NewsBundle\Controller\CommentAdminController');
2075
        $commentAdmin->setRequest($request);
2076
        $commentAdmin->setModelManager($modelManager);
2077
2078
        $this->assertTrue($commentAdmin->hasSubject());
2079
        $this->assertSame($comment, $commentAdmin->getSubject());
2080
2081
        $commentAdmin->setSubject(null);
2082
        $commentAdmin->setParentFieldDescription(new FieldDescription());
2083
2084
        $this->assertFalse($commentAdmin->hasSubject());
2085
    }
2086
2087
    /**
2088
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2089
     */
2090
    public function testGetActionButtonsList(): void
2091
    {
2092
        $expected = [
2093
            'create' => [
2094
                'template' => 'Foo.html.twig',
2095
            ],
2096
        ];
2097
2098
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2099
2100
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
2101
        $templateRegistry->getTemplate('button_create')->willReturn('Foo.html.twig');
2102
2103
        $admin->setTemplateRegistry($templateRegistry->reveal());
2104
2105
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2106
        $securityHandler
2107
            ->expects($this->once())
2108
            ->method('isGranted')
2109
            ->with($admin, 'CREATE', $admin)
2110
            ->willReturn(true);
2111
        $admin->setSecurityHandler($securityHandler);
2112
2113
        $routeGenerator = $this->createMock(RouteGeneratorInterface::class);
2114
        $routeGenerator
2115
            ->expects($this->once())
2116
            ->method('hasAdminRoute')
2117
            ->with($admin, 'create')
2118
            ->willReturn(true);
2119
        $admin->setRouteGenerator($routeGenerator);
2120
2121
        $this->assertSame($expected, $admin->getActionButtons('list', null));
2122
    }
2123
2124
    /**
2125
     * @covers \Sonata\AdminBundle\Admin\AbstractAdmin::configureActionButtons
2126
     */
2127
    public function testGetActionButtonsListCreateDisabled(): void
2128
    {
2129
        $admin = new PostAdmin('sonata.post.admin.post', 'NewsBundle\Entity\Post', 'Sonata\NewsBundle\Controller\PostAdminController');
2130
2131
        $securityHandler = $this->createMock(SecurityHandlerInterface::class);
2132
        $securityHandler
2133
            ->expects($this->once())
2134
            ->method('isGranted')
2135
            ->with($admin, 'CREATE', $admin)
2136
            ->willReturn(false);
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([], $admin->getActionButtons('list', null));
2148
    }
2149
2150
    public function testGetActionButtonsListWithoutExtraChecks(): void
2151
    {
2152
        $admin = $this->getMockBuilder(AbstractAdmin::class)
2153
            ->disableOriginalConstructor()
2154
            ->setMethodsExcept(['getActionButtons', 'configureActionButtons'])
2155
            ->getMockForAbstractClass();
2156
2157
        $admin->method('isAclEnabled')->willReturn(true);
2158
        $admin->method('getExtensions')->willReturn([]);
2159
2160
        $admin->expects($this->exactly(9))->method('hasRoute')->willReturn(false);
2161
        $admin->expects($this->never())->method('hasAccess');
2162
        $admin->expects($this->never())->method('getShow');
2163
2164
        $this->assertSame([], $admin->getActionButtons('show'));
2165
        $this->assertSame([], $admin->getActionButtons('edit'));
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