Completed
Push — master ( 1c0828...c11e72 )
by Marko
04:18
created

PoolTest::testGetAdminByAdminCodeWithInvalidCode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.568
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Tests\Admin;
15
16
use 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);
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
    public function testGetAdminByAdminCodeWithInvalidCode(): void
229
    {
230
        $adminMock = $this->getMockBuilder(AdminInterface::class)
231
            ->disableOriginalConstructor()
232
            ->getMock();
233
        $adminMock->expects($this->any())
234
            ->method('hasChild')
235
            ->willReturn(false);
236
237
        $containerMock = $this->createMock(ContainerInterface::class);
238
        $containerMock->expects($this->any())
239
            ->method('get')
240
            ->willReturn($adminMock);
241
242
        $this->pool = new Pool($containerMock, 'Sonata', '/path/to/logo.png');
243
        $this->pool->setAdminServiceIds(['sonata.news.admin.post']);
244
245
        $this->expectException(\InvalidArgumentException::class);
246
        $this->expectExceptionMessage('Argument 1 passed to Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() must contain a valid admin reference, "sonata.news.admin.valid" found at "sonata.news.admin.post|sonata.news.admin.valid".');
247
248
        $this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.valid');
249
    }
250
251
    public function testGetAdminByAdminCodeWithCodeNotChild(): void
252
    {
253
        $adminMock = $this->getMockBuilder(AdminInterface::class)
254
            ->disableOriginalConstructor()
255
            ->getMock();
256
        $adminMock->expects($this->any())
257
            ->method('hasChild')
258
            ->willReturn(false);
259
260
        $containerMock = $this->createMock(ContainerInterface::class);
261
        $containerMock->expects($this->any())
262
            ->method('get')
263
            ->willReturn($adminMock);
264
265
        $this->pool = new Pool($containerMock, 'Sonata', '/path/to/logo.png');
266
        $this->pool->setAdminServiceIds(['sonata.news.admin.post', 'sonata.news.admin.valid']);
267
268
        $this->assertFalse($this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.valid'));
269
    }
270
271
    /**
272
     * @dataProvider getEmptyRootAdminServiceNames
273
     */
274
    public function testGetAdminByAdminCodeWithInvalidRootCode(string $adminId): void
275
    {
276
        $adminMock = $this->createMock(AdminInterface::class);
277
        $adminMock->expects($this->never())
278
            ->method('hasChild');
279
280
        $containerMock = $this->createMock(ContainerInterface::class);
281
        $containerMock->expects($this->never())
282
            ->method('get');
283
284
        $poolMock = $this->getMockBuilder(Pool::class)
285
            ->setConstructorArgs([$containerMock, 'Sonata', '/path/to/logo.png'])
286
            ->disableOriginalClone()
287
            ->setMethodsExcept(['getAdminByAdminCode'])
288
            ->getMock();
289
        $poolMock->expects($this->never())
290
            ->method('getInstance');
291
292
        $this->expectException(\InvalidArgumentException::class);
293
        $this->expectExceptionMessage('Root admin code must contain a valid admin reference, empty string given.');
294
        $poolMock->getAdminByAdminCode($adminId);
295
    }
296
297
    public function getEmptyRootAdminServiceNames()
298
    {
299
        return [
300
            [''],
301
            ['   '],
302
            ['|sonata.news.admin.child_of_empty_code'],
303
        ];
304
    }
305
306
    /**
307
     * @dataProvider getInvalidChildAdminServiceNames
308
     */
309
    public function testGetAdminByAdminCodeWithInvalidChildCode(string $adminId): void
310
    {
311
        $adminMock = $this->createMock(AdminInterface::class);
312
        $adminMock->expects($this->any())
313
            ->method('hasChild')
314
            ->willReturn(false);
315
        $adminMock->expects($this->never())
316
            ->method('getChild');
317
318
        $containerMock = $this->createMock(ContainerInterface::class);
319
        $containerMock->expects($this->never())
320
            ->method('get');
321
322
        $poolMock = $this->getMockBuilder(Pool::class)
323
            ->setConstructorArgs([$containerMock, 'Sonata', '/path/to/logo.png'])
324
            ->disableOriginalClone()
325
            ->setMethodsExcept(['getAdminByAdminCode'])
326
            ->getMock();
327
        $poolMock->expects($this->any())
328
            ->method('getInstance')
329
            ->willReturn($adminMock);
330
331
        $this->expectExceptionMessageRegExp(sprintf(
332
            '{^Argument 1 passed to Sonata\\\AdminBundle\\\Admin\\\Pool::getAdminByAdminCode\(\) must contain a valid admin reference, "[^"]+" found at "%s"\.$}',
333
            $adminId
334
        ));
335
336
        $poolMock->getAdminByAdminCode($adminId);
337
    }
338
339
    public function getInvalidChildAdminServiceNames()
340
    {
341
        return [
342
            ['admin1|'],
343
            ['admin1|nonexistent_code'],
344
            ['admin1||admin3'],
345
        ];
346
    }
347
348
    public function testGetAdminClasses(): void
349
    {
350
        $this->pool->setAdminClasses(['someclass' => 'sonata.user.admin.group1']);
351
        $this->assertSame(['someclass' => 'sonata.user.admin.group1'], $this->pool->getAdminClasses());
352
    }
353
354
    public function testGetAdminGroups(): void
355
    {
356
        $this->pool->setAdminGroups(['adminGroup1' => 'sonata.user.admin.group1']);
357
        $this->assertSame(['adminGroup1' => 'sonata.user.admin.group1'], $this->pool->getAdminGroups());
358
    }
359
360
    public function testGetAdminServiceIds(): void
361
    {
362
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3']);
363
        $this->assertSame(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3'], $this->pool->getAdminServiceIds());
364
    }
365
366
    public function testGetContainer(): void
367
    {
368
        $this->assertInstanceOf(ContainerInterface::class, $this->pool->getContainer());
369
    }
370
371
    /**
372
     * @group legacy
373
     */
374
    public function testTemplate(): void
375
    {
376
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
377
        $templateRegistry->getTemplate('ajax')
378
            ->shouldBeCalledTimes(1)
379
            ->willReturn('Foo.html.twig');
380
381
        $this->pool->setTemplateRegistry($templateRegistry->reveal());
382
383
        $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...
384
    }
385
386
    /**
387
     * @group legacy
388
     */
389
    public function testSetGetTemplates(): void
390
    {
391
        $templates = [
392
            'ajax' => 'Foo.html.twig',
393
            'layout' => 'Bar.html.twig',
394
        ];
395
396
        $templateRegistry = $this->prophesize(MutableTemplateRegistryInterface::class);
397
        $templateRegistry->setTemplates($templates)
398
            ->shouldBeCalledTimes(1);
399
        $templateRegistry->getTemplates()
400
            ->shouldBeCalledTimes(1)
401
            ->willReturn($templates);
402
403
        $this->pool->setTemplateRegistry($templateRegistry->reveal());
404
405
        $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...
406
407
        $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...
408
    }
409
410
    public function testGetTitleLogo(): void
411
    {
412
        $this->assertSame('/path/to/pic.png', $this->pool->getTitleLogo());
413
    }
414
415
    public function testGetTitle(): void
416
    {
417
        $this->assertSame('Sonata Admin', $this->pool->getTitle());
418
    }
419
420
    public function testGetOption(): void
421
    {
422
        $this->assertSame('bar', $this->pool->getOption('foo'));
423
424
        $this->assertNull($this->pool->getOption('non_existent_option'));
425
    }
426
427
    public function testOptionDefault(): void
428
    {
429
        $this->assertSame([], $this->pool->getOption('nonexistantarray', []));
430
    }
431
432
    private function getContainer(): ContainerInterface
433
    {
434
        $containerMock = $this->createMock(ContainerInterface::class);
435
        $containerMock->expects($this->any())
436
            ->method('get')
437
            ->willReturnCallback(function () {
438
                return $this->createMock(AdminInterface::class);
439
            });
440
441
        return $containerMock;
442
    }
443
444
    private function getItemArray($serviceId): array
445
    {
446
        return [
447
            'admin' => $serviceId,
448
            'label' => '',
449
            'route' => '',
450
            'route_params' => [],
451
        ];
452
    }
453
}
454