Completed
Push — 3.x ( e95e95...638cd1 )
by Oskar
05:54
created

tests/Admin/PoolTest.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 PHPUnit\Framework\TestCase;
17
use Sonata\AdminBundle\Admin\AdminInterface;
18
use Sonata\AdminBundle\Admin\Pool;
19
use Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface;
20
use Symfony\Component\DependencyInjection\ContainerInterface;
21
22
class PoolTest extends TestCase
23
{
24
    /**
25
     * @var Pool
26
     */
27
    private $pool = null;
28
29
    public function setUp(): void
30
    {
31
        $this->pool = new Pool($this->getContainer(), 'Sonata Admin', '/path/to/pic.png', ['foo' => 'bar']);
32
    }
33
34
    public function testGetGroups(): void
35
    {
36
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1']);
37
38
        $this->pool->setAdminGroups([
39
            'adminGroup1' => ['sonata.user.admin.group1' => []],
40
        ]);
41
42
        $result = $this->pool->getGroups();
43
        $this->assertArrayHasKey('adminGroup1', $result);
44
        $this->assertArrayHasKey('sonata.user.admin.group1', $result['adminGroup1']);
45
    }
46
47
    public function testHasGroup(): void
48
    {
49
        $this->pool->setAdminGroups([
50
                'adminGroup1' => [],
51
            ]);
52
53
        $this->assertTrue($this->pool->hasGroup('adminGroup1'));
54
        $this->assertFalse($this->pool->hasGroup('adminGroup2'));
55
    }
56
57
    public function testGetDashboardGroups(): void
58
    {
59
        $admin_group1 = $this->createMock(AdminInterface::class);
60
        $admin_group1->expects($this->once())->method('showIn')->willReturn(true);
61
62
        $admin_group2 = $this->createMock(AdminInterface::class);
63
        $admin_group2->expects($this->once())->method('showIn')->willReturn(false);
64
65
        $admin_group3 = $this->createMock(AdminInterface::class);
66
        $admin_group3->expects($this->once())->method('showIn')->willReturn(false);
67
68
        $container = $this->createMock(ContainerInterface::class);
69
70
        $container->expects($this->any())->method('get')->will($this->onConsecutiveCalls(
71
            $admin_group1, $admin_group2, $admin_group3
72
        ));
73
74
        $pool = new Pool($container, 'Sonata Admin', '/path/to/pic.png');
75
        $pool->setAdminServiceIds(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3']);
76
77
        $pool->setAdminGroups([
78
            'adminGroup1' => [
79
                'items' => ['itemKey' => $this->getItemArray('sonata.user.admin.group1')],
80
            ],
81
            'adminGroup2' => [
82
                'items' => ['itemKey' => $this->getItemArray('sonata.user.admin.group2')],
83
            ],
84
            'adminGroup3' => [
85
                'items' => ['itemKey' => $this->getItemArray('sonata.user.admin.group3')],
86
            ],
87
        ]);
88
89
        $groups = $pool->getDashboardGroups();
90
91
        $this->assertCount(1, $groups);
0 ignored issues
show
$groups is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

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...
92
        $this->assertSame($admin_group1, $groups['adminGroup1']['items']['itemKey']);
93
    }
94
95
    public function testGetAdminsByGroupWhenGroupNotSet(): void
96
    {
97
        $this->expectException(\InvalidArgumentException::class);
98
99
        $this->pool->setAdminGroups([
100
                'adminGroup1' => [],
101
            ]);
102
103
        $this->pool->getAdminsByGroup('adminGroup2');
104
    }
105
106
    public function testGetAdminsByGroupWhenGroupIsEmpty(): void
107
    {
108
        $this->pool->setAdminGroups([
109
                'adminGroup1' => [],
110
            ]);
111
112
        $this->assertSame([], $this->pool->getAdminsByGroup('adminGroup1'));
113
    }
114
115
    public function testGetAdminsByGroup(): void
116
    {
117
        $this->pool->setAdminServiceIds(['sonata.admin1', 'sonata.admin2', 'sonata.admin3']);
118
        $this->pool->setAdminGroups([
119
            'adminGroup1' => [
120
                'items' => [
121
                    $this->getItemArray('sonata.admin1'),
122
                    $this->getItemArray('sonata.admin2'),
123
                ],
124
            ],
125
            'adminGroup2' => [
126
                'items' => [$this->getItemArray('sonata.admin3')],
127
            ],
128
        ]);
129
130
        $this->assertCount(2, $this->pool->getAdminsByGroup('adminGroup1'));
131
        $this->assertCount(1, $this->pool->getAdminsByGroup('adminGroup2'));
132
    }
133
134
    public function testGetAdminForClassWhenAdminClassIsNotSet(): void
135
    {
136
        $this->pool->setAdminClasses(['someclass' => 'sonata.user.admin.group1']);
137
        $this->assertFalse($this->pool->hasAdminByClass('notexists'));
138
        $this->assertNull($this->pool->getAdminByClass('notexists'));
139
    }
140
141
    public function testGetAdminForClassWithInvalidFormat(): void
142
    {
143
        $this->expectException(\RuntimeException::class);
144
145
        $this->pool->setAdminClasses(['someclass' => 'sonata.user.admin.group1']);
146
        $this->assertTrue($this->pool->hasAdminByClass('someclass'));
147
148
        $this->pool->getAdminByClass('someclass');
149
    }
150
151
    public function testGetAdminForClassWithTooManyRegisteredAdmin(): void
152
    {
153
        $this->expectException(\RuntimeException::class);
154
155
        $this->pool->setAdminClasses([
156
            'someclass' => ['sonata.user.admin.group1', 'sonata.user.admin.group2'],
157
        ]);
158
159
        $this->assertTrue($this->pool->hasAdminByClass('someclass'));
160
        $this->pool->getAdminByClass('someclass');
161
    }
162
163
    public function testGetAdminForClassWhenAdminClassIsSet(): void
164
    {
165
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1']);
166
        $this->pool->setAdminClasses([
167
            'someclass' => ['sonata.user.admin.group1'],
168
        ]);
169
170
        $this->assertTrue($this->pool->hasAdminByClass('someclass'));
171
        $this->assertInstanceOf(AdminInterface::class, $this->pool->getAdminByClass('someclass'));
172
    }
173
174
    public function testGetInstanceWithUndefinedServiceId(): void
175
    {
176
        $this->expectException(\InvalidArgumentException::class);
177
        $this->expectExceptionMessage('Admin service "sonata.news.admin.post" not found in admin pool.');
178
179
        $this->pool->getInstance('sonata.news.admin.post');
180
    }
181
182
    public function testGetInstanceWithUndefinedServiceIdAndExistsOther(): void
183
    {
184
        $this->pool->setAdminServiceIds([
185
            'sonata.news.admin.post',
186
            'sonata.news.admin.category',
187
        ]);
188
189
        $this->expectException(\InvalidArgumentException::class);
190
        $this->expectExceptionMessage('Admin service "sonata.news.admin.pos" not found in admin pool. '
191
            .'Did you mean "sonata.news.admin.post" '
192
            .'or one of those: [sonata.news.admin.category]?');
193
194
        $this->pool->getInstance('sonata.news.admin.pos');
195
    }
196
197
    public function testGetAdminByAdminCode(): void
198
    {
199
        $this->pool->setAdminServiceIds(['sonata.news.admin.post']);
200
201
        $this->assertInstanceOf(AdminInterface::class, $this->pool->getAdminByAdminCode('sonata.news.admin.post'));
202
    }
203
204
    public function testGetAdminByAdminCodeForChildClass(): void
205
    {
206
        $adminMock = $this->getMockBuilder(AdminInterface::class)
207
            ->disableOriginalConstructor()
208
            ->getMock();
209
        $adminMock->expects($this->any())
210
            ->method('hasChild')
211
            ->willReturn(true);
212
        $adminMock->expects($this->once())
213
            ->method('getChild')
214
            ->with($this->equalTo('sonata.news.admin.comment'))
215
            ->willReturn('commentAdminClass');
216
217
        $containerMock = $this->createMock(ContainerInterface::class);
218
        $containerMock->expects($this->any())
219
            ->method('get')
220
            ->willReturn($adminMock);
221
222
        $this->pool = new Pool($containerMock, 'Sonata', '/path/to/logo.png');
223
        $this->pool->setAdminServiceIds(['sonata.news.admin.post', 'sonata.news.admin.comment']);
224
225
        $this->assertSame('commentAdminClass', $this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.comment'));
226
    }
227
228
    /**
229
     * @group legacy
230
     *
231
     * @expectedDeprecation Passing an invalid admin code as argument 1 for Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() is deprecated since sonata-project/admin-bundle 3.50 and will throw an exception in 4.0.
232
     */
233
    public function testGetAdminByAdminCodeWithInvalidCode(): void
234
    {
235
        $adminMock = $this->getMockBuilder(AdminInterface::class)
236
            ->disableOriginalConstructor()
237
            ->getMock();
238
        $adminMock->expects($this->any())
239
            ->method('hasChild')
240
            ->willReturn(false);
241
242
        $containerMock = $this->createMock(ContainerInterface::class);
243
        $containerMock->expects($this->any())
244
            ->method('get')
245
            ->willReturn($adminMock);
246
247
        $this->pool = new Pool($containerMock, 'Sonata', '/path/to/logo.png');
248
        $this->pool->setAdminServiceIds(['sonata.news.admin.post']);
249
250
        $this->assertFalse($this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.invalid'));
251
    }
252
253
    /**
254
     * @group legacy
255
     *
256
     * @expectedDeprecation Passing a non string value as argument 1 for Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() is deprecated since sonata-project/admin-bundle 3.x and will throw an exception in 4.0.
257
     */
258
    public function testGetAdminByAdminCodeWithNonStringCode(): void
259
    {
260
        $this->pool = new Pool($this->createMock(ContainerInterface::class), 'Sonata', '/path/to/logo.png');
261
262
        $this->assertFalse($this->pool->getAdminByAdminCode(false));
263
        $this->assertFalse($this->pool->getAdminByAdminCode(true));
264
        $this->assertFalse($this->pool->getAdminByAdminCode(null));
265
        $this->assertFalse($this->pool->getAdminByAdminCode(['']));
266
        $this->assertFalse($this->pool->getAdminByAdminCode(['some_value']));
267
        $this->assertFalse($this->pool->getAdminByAdminCode(1));
268
        $this->assertFalse($this->pool->getAdminByAdminCode(new \stdClass()));
269
        // NEXT_MAJOR: remove the previous assertions, the "@group" and "@expectedDeprecation" annotations, and uncomment the following line
270
        // $this->expectException(\TypeError::class);
271
    }
272
273
    /**
274
     * @group legacy
275
     *
276
     * @expectedDeprecation Passing an invalid admin hierarchy inside argument 1 for Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() is deprecated since sonata-project/admin-bundle 3.x and will throw an exception in 4.0.
277
     */
278
    public function testGetAdminByAdminCodeWithCodeNotChild(): void
279
    {
280
        $adminMock = $this->getMockBuilder(AdminInterface::class)
281
            ->disableOriginalConstructor()
282
            ->getMock();
283
        $adminMock->expects($this->any())
284
            ->method('hasChild')
285
            ->willReturn(false);
286
        $adminMock->expects($this->any())
287
            ->method('getCode')
288
            ->willReturn('sonata.news.admin.post');
289
        $containerMock = $this->createMock(ContainerInterface::class);
290
        $containerMock->expects($this->any())
291
            ->method('get')
292
            ->willReturn($adminMock);
293
        $this->pool = new Pool($containerMock, 'Sonata', '/path/to/logo.png');
294
        $this->pool->setAdminServiceIds(['sonata.news.admin.post', 'sonata.news.admin.valid']);
295
        $this->assertFalse($this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.valid'));
296
        // NEXT_MAJOR: remove the "@group" and "@expectedDeprecation" annotations, the previous assertion and uncomment the following lines
297
        // $this->expectException(\InvalidArgumentException::class);
298
        // $this->expectExceptionMessage('Argument 1 passed to Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() must contain a valid admin hierarchy, "sonata.news.admin.valid" is not a valid child for "sonata.news.admin.post"');
299
        //
300
        // $this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.valid');
301
    }
302
303
    /**
304
     * @dataProvider getEmptyRootAdminServiceNames
305
     */
306
    public function testGetAdminByAdminCodeWithInvalidRootCode(string $adminId): void
307
    {
308
        $adminMock = $this->createMock(AdminInterface::class);
309
        $adminMock->expects($this->never())
310
            ->method('hasChild');
311
312
        $containerMock = $this->createMock(ContainerInterface::class);
313
        $containerMock->expects($this->never())
314
            ->method('get');
315
316
        $poolMock = $this->getMockBuilder(Pool::class)
317
            ->setConstructorArgs([$containerMock, 'Sonata', '/path/to/logo.png'])
318
            ->disableOriginalClone()
319
            ->setMethodsExcept(['getAdminByAdminCode'])
320
            ->getMock();
321
        $poolMock->expects($this->never())
322
            ->method('getInstance');
323
324
        $this->expectException(\InvalidArgumentException::class);
325
        $this->expectExceptionMessage('Root admin code must contain a valid admin reference, empty string given.');
326
        $poolMock->getAdminByAdminCode($adminId);
327
    }
328
329
    public function getEmptyRootAdminServiceNames()
330
    {
331
        return [
332
            [''],
333
            ['   '],
334
            ['|sonata.news.admin.child_of_empty_code'],
335
        ];
336
    }
337
338
    /**
339
     * @dataProvider getInvalidChildAdminServiceNames
340
     *
341
     * @group legacy
342
     *
343
     * @expectedDeprecation Passing an invalid admin code as argument 1 for Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() is deprecated since sonata-project/admin-bundle 3.50 and will throw an exception in 4.0.
344
     */
345
    public function testGetAdminByAdminCodeWithInvalidChildCode(string $adminId): void
346
    {
347
        $adminMock = $this->createMock(AdminInterface::class);
348
        $adminMock->expects($this->any())
349
            ->method('hasChild')
350
            ->willReturn(false);
351
        $adminMock->expects($this->never())
352
            ->method('getChild');
353
354
        $containerMock = $this->createMock(ContainerInterface::class);
355
        $containerMock->expects($this->never())
356
            ->method('get');
357
358
        $poolMock = $this->getMockBuilder(Pool::class)
359
            ->setConstructorArgs([$containerMock, 'Sonata', '/path/to/logo.png'])
360
            ->disableOriginalClone()
361
            ->setMethodsExcept(['getAdminByAdminCode'])
362
            ->getMock();
363
        $poolMock->expects($this->any())
364
            ->method('getInstance')
365
            ->willReturn($adminMock);
366
367
        $this->assertFalse($poolMock->getAdminByAdminCode($adminId));
368
    }
369
370
    public function getInvalidChildAdminServiceNames()
371
    {
372
        return [
373
            ['admin1|'],
374
            ['admin1|nonexistent_code'],
375
            ['admin1||admin3'],
376
        ];
377
    }
378
379
    public function testGetAdminClasses(): void
380
    {
381
        $this->pool->setAdminClasses(['someclass' => 'sonata.user.admin.group1']);
382
        $this->assertSame(['someclass' => 'sonata.user.admin.group1'], $this->pool->getAdminClasses());
383
    }
384
385
    public function testGetAdminGroups(): void
386
    {
387
        $this->pool->setAdminGroups(['adminGroup1' => 'sonata.user.admin.group1']);
388
        $this->assertSame(['adminGroup1' => 'sonata.user.admin.group1'], $this->pool->getAdminGroups());
389
    }
390
391
    public function testGetAdminServiceIds(): void
392
    {
393
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3']);
394
        $this->assertSame(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3'], $this->pool->getAdminServiceIds());
395
    }
396
397
    public function testGetContainer(): void
398
    {
399
        $this->assertInstanceOf(ContainerInterface::class, $this->pool->getContainer());
400
    }
401
402
    /**
403
     * @group legacy
404
     */
405
    public function testTemplate(): void
406
    {
407
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
408
        $templateRegistry->getTemplate('ajax')
409
            ->shouldBeCalledTimes(1)
410
            ->willReturn('Foo.html.twig');
411
412
        $this->pool->setTemplateRegistry($templateRegistry->reveal());
413
414
        $this->assertSame('Foo.html.twig', $this->pool->getTemplate('ajax'));
415
    }
416
417
    /**
418
     * @group legacy
419
     */
420
    public function testSetGetTemplates(): void
421
    {
422
        $templates = [
423
            'ajax' => 'Foo.html.twig',
424
            'layout' => 'Bar.html.twig',
425
        ];
426
427
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
428
        $templateRegistry->setTemplates($templates)
429
            ->shouldBeCalledTimes(1);
430
        $templateRegistry->getTemplates()
431
            ->shouldBeCalledTimes(1)
432
            ->willReturn($templates);
433
434
        $this->pool->setTemplateRegistry($templateRegistry->reveal());
435
436
        $this->pool->setTemplates($templates);
437
438
        $this->assertSame($templates, $this->pool->getTemplates());
439
    }
440
441
    public function testGetTitleLogo(): void
442
    {
443
        $this->assertSame('/path/to/pic.png', $this->pool->getTitleLogo());
444
    }
445
446
    public function testGetTitle(): void
447
    {
448
        $this->assertSame('Sonata Admin', $this->pool->getTitle());
449
    }
450
451
    public function testGetOption(): void
452
    {
453
        $this->assertSame('bar', $this->pool->getOption('foo'));
454
455
        $this->assertNull($this->pool->getOption('non_existent_option'));
456
    }
457
458
    public function testOptionDefault(): void
459
    {
460
        $this->assertSame([], $this->pool->getOption('nonexistantarray', []));
461
    }
462
463
    private function getContainer(): ContainerInterface
464
    {
465
        $containerMock = $this->createMock(ContainerInterface::class);
466
        $containerMock->expects($this->any())
467
            ->method('get')
468
            ->willReturnCallback(function () {
469
                return $this->createMock(AdminInterface::class);
470
            });
471
472
        return $containerMock;
473
    }
474
475
    private function getItemArray($serviceId): array
476
    {
477
        return [
478
            'admin' => $serviceId,
479
            'label' => '',
480
            'route' => '',
481
            'route_params' => [],
482
        ];
483
    }
484
}
485