Completed
Push — master ( 2eb0ca...af375c )
by Marko
14s
created

AdminTest   F

Complexity

Total Complexity 131

Size/Duplication

Total Lines 2337
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 23

Importance

Changes 0
Metric Value
wmc 131
lcom 1
cbo 23
dl 0
loc 2337
rs 0.8
c 0
b 0
f 0

114 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 6 1
A testConstructor() 0 10 1
A testGetClass() 0 23 1
A testGetClassException() 0 14 1
A testCheckAccessThrowsExceptionOnMadeUpAction() 0 15 1
A testCheckAccessThrowsAccessDeniedException() 0 24 1
A testHasAccessOnMadeUpAction() 0 10 1
A testHasAccess() 0 19 1
A testHasAccessAllowsAccess() 0 19 1
A testHasAccessAllowsAccessEditAction() 0 18 1
A testConfigure() 0 15 1
A testConfigureWithValidParentAssociationMapping() 0 8 1
B provideGetBaseRoutePattern() 0 65 1
A testGetBaseRoutePattern() 0 5 1
A testGetBaseRoutePatternWithChildAdmin() 0 8 1
A testGetBaseRoutePatternWithTwoNestedChildAdmin() 0 18 1
A testGetBaseRoutePatternWithSpecifedPattern() 0 6 1
A testGetBaseRoutePatternWithChildAdminAndWithSpecifedPattern() 0 8 1
A testGetBaseRoutePatternWithUnreconizedClassname() 0 7 1
B provideGetBaseRouteName() 0 65 1
A testGetBaseRouteName() 0 6 1
A testGetBaseRouteNameWithUnreconizedClassname() 0 7 1
A testGetBaseRouteNameWithSpecifiedName() 0 6 1
A testGetBaseRouteNameWithChildAdminAndWithSpecifiedName() 0 8 1
A testGetBaseRouteNameWithTwoNestedChildAdminAndWithSpecifiedName() 0 22 1
A testChildren() 0 22 1
B testGetBaseRouteNameWithChildAdmin() 0 85 1
A testSetUniqid() 0 9 1
A testUniqidConsistency() 0 26 1
A testToString() 0 17 1
A testIsAclEnabled() 0 10 1
B testSubClass() 0 56 1
A testNonExistantSubclass() 0 15 1
A testOnlyOneSubclassNeededToBeActive() 0 8 1
A testAddSubClassIsDeprecated() 0 9 1
A testGetPerPageOptions() 0 13 2
A testGetLabelTranslatorStrategy() 0 10 1
A testGetRouteBuilder() 0 10 1
A testGetMenuFactory() 0 10 1
A testGetExtensions() 0 13 1
A testGetFilterTheme() 0 9 1
A testGetFormTheme() 0 10 1
A testGetValidator() 0 11 1
A testGetSecurityHandler() 0 10 1
A testGetSecurityInformation() 0 14 1
A testGetManagerType() 0 9 1
A testGetModelManager() 0 11 1
A testGetBaseCodeRoute() 0 22 1
A testGetRouteGenerator() 0 11 1
A testGetConfigurationPool() 0 13 1
A testGetShowBuilder() 0 11 1
A testGetListBuilder() 0 11 1
A testGetDatagridBuilder() 0 11 1
A testGetFormContractor() 0 11 1
A testGetRequest() 0 12 1
A testGetRequestWithException() 0 8 1
A testGetTranslationDomain() 0 9 1
A testGetTranslator() 0 11 1
A testGetShowGroups() 0 11 1
A testGetFormGroups() 0 11 1
A testGetMaxPageLinks() 0 9 1
A testGetMaxPerPage() 0 9 1
A testGetLabel() 0 9 1
A testGetBaseController() 0 9 1
A testGetTemplates() 0 17 1
A testGetTemplate1() 0 13 1
A testGetIdParameter() 0 31 1
A testGetExportFormats() 0 6 1
A testGetUrlsafeIdentifier() 0 15 1
A testDeterminedPerPageValue() 0 12 1
A testIsGranted() 0 26 5
A testSupportsPreviewMode() 0 6 1
A testGetPermissionsShow() 0 8 1
A testShowIn() 0 21 3
A testGetObjectIdentifier() 0 6 1
A testTrans() 0 15 1
A testTransWithMessageDomain() 0 14 1
A testTransChoice() 0 15 1
A testTransChoiceWithMessageDomain() 0 14 1
A testSetFilterPersister() 0 11 1
A testGetRootCode() 0 17 1
A testGetRoot() 0 17 1
A testGetExportFields() 0 13 1
A testGetPersistentParametersWithNoExtension() 0 6 1
A testGetPersistentParametersWithInvalidExtension() 0 13 1
A testGetPersistentParametersWithValidExtension() 0 15 1
A testGetFormWithNonCollectionParentValue() 0 10 1
A testGetFormWithCollectionParentValue() 0 34 1
B testFormAddPostSubmitEventForPreValidation() 0 60 2
A testRemoveFieldFromFormGroup() 0 26 1
A testGetFilterParameters() 0 34 1
B testGetFilterFieldDescription() 0 71 4
A testGetSubjectNoRequest() 0 12 1
A testGetSideMenu() 0 24 1
A provideGetSubject() 0 10 1
A testGetSubjectFailed() 0 15 1
A testGetSubject() 0 18 1
A testGetSubjectWithParentDescription() 0 29 1
A testGetActionButtonsList() 0 33 1
A testGetActionButtonsListCreateDisabled() 0 14 1
B testGetBatchActions() 0 58 3
A testShowMosaicButton() 0 9 1
A testShowMosaicButtonHideMosaic() 0 10 1
A testDefaultDashboardActionsArePresent() 0 35 4
B testDefaultFilters() 0 59 1
A testCreateQueryLegacyCallWorks() 0 14 1
A testGetDataSourceIterator() 0 42 2
A testCircularChildAdmin() 0 20 1
A testCircularChildAdminTripleLevel() 0 26 1
A testCircularChildAdminWithItself() 0 14 1
A testGetRootAncestor() 0 34 1
A testGetChildDepth() 0 34 1
A testGetCurrentLeafChildAdmin() 0 37 1
A createTagAdmin() 0 39 1

How to fix   Complexity   

Complex Class

Complex classes like AdminTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AdminTest, and based on these observations, apply Extract Interface, too.

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