Completed
Push — 3.x ( e7609d...62e5e7 )
by Grégoire
04:55
created

testGetAdminByAdminCodeWithInvalidChildCode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 9.536
c 0
b 0
f 0
cc 1
nc 1
nop 1
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');
0 ignored issues
show
Documentation introduced by
$container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Component...ion\ContainerInterface>.

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...
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
Documentation introduced by
$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'));
0 ignored issues
show
Documentation introduced by
$this->pool->getAdminsByGroup('adminGroup1') is of type array<integer,object<Son...\Admin\AdminInterface>>, 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...
131
        $this->assertCount(1, $this->pool->getAdminsByGroup('adminGroup2'));
0 ignored issues
show
Documentation introduced by
$this->pool->getAdminsByGroup('adminGroup2') is of type array<integer,object<Son...\Admin\AdminInterface>>, 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...
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');
0 ignored issues
show
Documentation introduced by
$containerMock is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Component...ion\ContainerInterface>.

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...
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 3.x and will throw an exception in 4.0.
232
     */
233
    public function testGetAdminByAdminCodeForChildInvalidClass(): 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');
0 ignored issues
show
Documentation introduced by
$containerMock is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Symfony\Component...ion\ContainerInterface>.

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...
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
     * @dataProvider getEmptyRootAdminServiceNames
255
     */
256
    public function testGetAdminByAdminCodeWithInvalidRootCode(string $adminId): void
257
    {
258
        $adminMock = $this->createMock(AdminInterface::class);
259
        $adminMock->expects($this->never())
260
            ->method('hasChild');
261
262
        $containerMock = $this->createMock(ContainerInterface::class);
263
        $containerMock->expects($this->never())
264
            ->method('get');
265
266
        $poolMock = $this->getMockBuilder(Pool::class)
267
            ->setConstructorArgs([$containerMock, 'Sonata', '/path/to/logo.png'])
268
            ->disableOriginalClone()
269
            ->setMethodsExcept(['getAdminByAdminCode'])
270
            ->getMock();
271
        $poolMock->expects($this->never())
272
            ->method('getInstance');
273
274
        $this->expectException(\InvalidArgumentException::class);
275
        $this->expectExceptionMessage('Root admin code must contain a valid admin reference, empty string given.');
276
        $poolMock->getAdminByAdminCode($adminId);
277
    }
278
279
    public function getEmptyRootAdminServiceNames()
280
    {
281
        return [
282
            [''],
283
            ['   '],
284
            ['|sonata.news.admin.child_of_empty_code'],
285
        ];
286
    }
287
288
    /**
289
     * @dataProvider getInvalidChildAdminServiceNames
290
     *
291
     * @group legacy
292
     *
293
     * @expectedDeprecation Passing an invalid admin code as argument 1 for Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() is deprecated since 3.x and will throw an exception in 4.0.
294
     */
295
    public function testGetAdminByAdminCodeWithInvalidChildCode(string $adminId): void
296
    {
297
        $adminMock = $this->createMock(AdminInterface::class);
298
        $adminMock->expects($this->any())
299
            ->method('hasChild')
300
            ->willReturn(false);
301
        $adminMock->expects($this->never())
302
            ->method('getChild');
303
304
        $containerMock = $this->createMock(ContainerInterface::class);
305
        $containerMock->expects($this->never())
306
            ->method('get');
307
308
        $poolMock = $this->getMockBuilder(Pool::class)
309
            ->setConstructorArgs([$containerMock, 'Sonata', '/path/to/logo.png'])
310
            ->disableOriginalClone()
311
            ->setMethodsExcept(['getAdminByAdminCode'])
312
            ->getMock();
313
        $poolMock->expects($this->any())
314
            ->method('getInstance')
315
            ->willReturn($adminMock);
316
317
        $this->assertFalse($poolMock->getAdminByAdminCode($adminId));
318
    }
319
320
    public function getInvalidChildAdminServiceNames()
321
    {
322
        return [
323
            ['admin1|'],
324
            ['admin1|nonexistent_code'],
325
            ['admin1||admin3'],
326
        ];
327
    }
328
329
    public function testGetAdminClasses(): void
330
    {
331
        $this->pool->setAdminClasses(['someclass' => 'sonata.user.admin.group1']);
332
        $this->assertSame(['someclass' => 'sonata.user.admin.group1'], $this->pool->getAdminClasses());
333
    }
334
335
    public function testGetAdminGroups(): void
336
    {
337
        $this->pool->setAdminGroups(['adminGroup1' => 'sonata.user.admin.group1']);
338
        $this->assertSame(['adminGroup1' => 'sonata.user.admin.group1'], $this->pool->getAdminGroups());
339
    }
340
341
    public function testGetAdminServiceIds(): void
342
    {
343
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3']);
344
        $this->assertSame(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3'], $this->pool->getAdminServiceIds());
345
    }
346
347
    public function testGetContainer(): void
348
    {
349
        $this->assertInstanceOf(ContainerInterface::class, $this->pool->getContainer());
350
    }
351
352
    /**
353
     * @group legacy
354
     */
355
    public function testTemplate(): void
356
    {
357
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
358
        $templateRegistry->getTemplate('ajax')
359
            ->shouldBeCalledTimes(1)
360
            ->willReturn('Foo.html.twig');
361
362
        $this->pool->setTemplateRegistry($templateRegistry->reveal());
363
364
        $this->assertSame('Foo.html.twig', $this->pool->getTemplate('ajax'));
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin\Pool::getTemplate() has been deprecated with message: since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" 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...
365
    }
366
367
    /**
368
     * @group legacy
369
     */
370
    public function testSetGetTemplates(): void
371
    {
372
        $templates = [
373
            'ajax' => 'Foo.html.twig',
374
            'layout' => 'Bar.html.twig',
375
        ];
376
377
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
378
        $templateRegistry->setTemplates($templates)
379
            ->shouldBeCalledTimes(1);
380
        $templateRegistry->getTemplates()
381
            ->shouldBeCalledTimes(1)
382
            ->willReturn($templates);
383
384
        $this->pool->setTemplateRegistry($templateRegistry->reveal());
385
386
        $this->pool->setTemplates($templates);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin\Pool::setTemplates() has been deprecated with message: since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" 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...
387
388
        $this->assertSame($templates, $this->pool->getTemplates());
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin\Pool::getTemplates() has been deprecated with message: since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" 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...
389
    }
390
391
    public function testGetTitleLogo(): void
392
    {
393
        $this->assertSame('/path/to/pic.png', $this->pool->getTitleLogo());
394
    }
395
396
    public function testGetTitle(): void
397
    {
398
        $this->assertSame('Sonata Admin', $this->pool->getTitle());
399
    }
400
401
    public function testGetOption(): void
402
    {
403
        $this->assertSame('bar', $this->pool->getOption('foo'));
404
405
        $this->assertNull($this->pool->getOption('non_existent_option'));
406
    }
407
408
    public function testOptionDefault(): void
409
    {
410
        $this->assertSame([], $this->pool->getOption('nonexistantarray', []));
411
    }
412
413
    private function getContainer(): ContainerInterface
414
    {
415
        $containerMock = $this->createMock(ContainerInterface::class);
416
        $containerMock->expects($this->any())
417
            ->method('get')
418
            ->willReturnCallback(function () {
419
                return $this->createMock(AdminInterface::class);
420
            });
421
422
        return $containerMock;
423
    }
424
425
    private function getItemArray($serviceId): array
426
    {
427
        return [
428
            'admin' => $serviceId,
429
            'label' => '',
430
            'route' => '',
431
            'route_params' => [],
432
        ];
433
    }
434
}
435