PoolTest::testGetGroups()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
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\MockObject\MockObject;
17
use PHPUnit\Framework\TestCase;
18
use Sonata\AdminBundle\Admin\AdminInterface;
19
use Sonata\AdminBundle\Admin\Pool;
20
use Symfony\Component\DependencyInjection\Container;
21
use Symfony\Component\DependencyInjection\ContainerInterface;
22
23
class PoolTest extends TestCase
24
{
25
    /**
26
     * @var Container
27
     */
28
    private $container;
29
30
    /**
31
     * @var Pool
32
     */
33
    private $pool;
34
35
    protected function setUp(): void
36
    {
37
        $this->container = new Container();
38
        $this->pool = new Pool($this->container, 'Sonata Admin', '/path/to/pic.png', ['foo' => 'bar']);
39
    }
40
41
    public function testGetGroups(): void
42
    {
43
        $this->container->set('sonata.user.admin.group1', $this->createMock(AdminInterface::class));
44
45
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1']);
46
47
        $this->pool->setAdminGroups([
48
            'adminGroup1' => ['sonata.user.admin.group1' => []],
49
        ]);
50
51
        $result = $this->pool->getGroups();
52
        $this->assertArrayHasKey('adminGroup1', $result);
53
        $this->assertArrayHasKey('sonata.user.admin.group1', $result['adminGroup1']);
54
    }
55
56
    public function testHasGroup(): void
57
    {
58
        $this->pool->setAdminGroups([
59
            'adminGroup1' => [],
60
        ]);
61
62
        $this->assertTrue($this->pool->hasGroup('adminGroup1'));
63
        $this->assertFalse($this->pool->hasGroup('adminGroup2'));
64
    }
65
66
    public function testGetDashboardGroups(): void
67
    {
68
        $adminGroup1 = $this->createMock(AdminInterface::class);
69
        $adminGroup1->expects($this->once())->method('showIn')->willReturn(true);
70
71
        $adminGroup2 = $this->createMock(AdminInterface::class);
72
        $adminGroup2->expects($this->once())->method('showIn')->willReturn(false);
73
74
        $adminGroup3 = $this->createMock(AdminInterface::class);
75
        $adminGroup3->expects($this->once())->method('showIn')->willReturn(false);
76
77
        $this->container->set('sonata.user.admin.group1', $adminGroup1);
78
        $this->container->set('sonata.user.admin.group2', $adminGroup2);
79
        $this->container->set('sonata.user.admin.group3', $adminGroup3);
80
81
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3']);
82
83
        $this->pool->setAdminGroups([
84
            'adminGroup1' => [
85
                'items' => ['itemKey' => $this->getItemArray('sonata.user.admin.group1')],
86
            ],
87
            'adminGroup2' => [
88
                'items' => ['itemKey' => $this->getItemArray('sonata.user.admin.group2')],
89
            ],
90
            'adminGroup3' => [
91
                'items' => ['itemKey' => $this->getItemArray('sonata.user.admin.group3')],
92
            ],
93
        ]);
94
95
        $groups = $this->pool->getDashboardGroups();
96
97
        $this->assertCount(1, $groups);
98
        $this->assertSame($adminGroup1, $groups['adminGroup1']['items']['itemKey']);
99
    }
100
101
    public function testGetAdminsByGroupWhenGroupNotSet(): void
102
    {
103
        $this->expectException(\InvalidArgumentException::class);
104
105
        $this->pool->setAdminGroups([
106
                'adminGroup1' => [],
107
            ]);
108
109
        $this->pool->getAdminsByGroup('adminGroup2');
110
    }
111
112
    public function testGetAdminsByGroupWhenGroupIsEmpty(): void
113
    {
114
        $this->pool->setAdminGroups([
115
                'adminGroup1' => [],
116
            ]);
117
118
        $this->assertSame([], $this->pool->getAdminsByGroup('adminGroup1'));
119
    }
120
121
    public function testGetAdminsByGroup(): void
122
    {
123
        $this->container->set('sonata.admin1', $this->createMock(AdminInterface::class));
124
        $this->container->set('sonata.admin2', $this->createMock(AdminInterface::class));
125
        $this->container->set('sonata.admin3', $this->createMock(AdminInterface::class));
126
127
        $this->pool->setAdminServiceIds(['sonata.admin1', 'sonata.admin2', 'sonata.admin3']);
128
        $this->pool->setAdminGroups([
129
            'adminGroup1' => [
130
                'items' => [
131
                    $this->getItemArray('sonata.admin1'),
132
                    $this->getItemArray('sonata.admin2'),
133
                ],
134
            ],
135
            'adminGroup2' => [
136
                'items' => [$this->getItemArray('sonata.admin3')],
137
            ],
138
        ]);
139
140
        $this->assertCount(2, $this->pool->getAdminsByGroup('adminGroup1'));
141
        $this->assertCount(1, $this->pool->getAdminsByGroup('adminGroup2'));
142
    }
143
144
    public function testGetAdminForClassWithInvalidFormat(): void
145
    {
146
        $this->expectException(\RuntimeException::class);
147
148
        $this->pool->setAdminClasses(['someclass' => 'sonata.user.admin.group1']);
149
        $this->assertTrue($this->pool->hasAdminByClass('someclass'));
150
151
        $this->pool->getAdminByClass('someclass');
152
    }
153
154
    public function testGetAdminForClassWithTooManyRegisteredAdmin(): void
155
    {
156
        $this->expectException(\RuntimeException::class);
157
158
        $this->pool->setAdminClasses([
159
            'someclass' => ['sonata.user.admin.group1', 'sonata.user.admin.group2'],
160
        ]);
161
162
        $this->assertTrue($this->pool->hasAdminByClass('someclass'));
163
        $this->pool->getAdminByClass('someclass');
164
    }
165
166
    public function testGetAdminForClassWhenAdminClassIsSet(): void
167
    {
168
        $this->container->set('sonata.user.admin.group1', $this->createMock(AdminInterface::class));
169
170
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1']);
171
        $this->pool->setAdminClasses([
172
            'someclass' => ['sonata.user.admin.group1'],
173
        ]);
174
175
        $this->assertTrue($this->pool->hasAdminByClass('someclass'));
176
        $this->assertInstanceOf(AdminInterface::class, $this->pool->getAdminByClass('someclass'));
177
    }
178
179
    public function testGetInstanceWithUndefinedServiceId(): void
180
    {
181
        $this->expectException(\InvalidArgumentException::class);
182
        $this->expectExceptionMessage('Admin service "sonata.news.admin.post" not found in admin pool.');
183
184
        $this->pool->getInstance('sonata.news.admin.post');
185
    }
186
187
    public function testGetInstanceWithUndefinedServiceIdAndExistsOther(): void
188
    {
189
        $this->pool->setAdminServiceIds([
190
            'sonata.news.admin.post',
191
            'sonata.news.admin.category',
192
        ]);
193
194
        $this->expectException(\InvalidArgumentException::class);
195
        $this->expectExceptionMessage('Admin service "sonata.news.admin.pos" not found in admin pool. Did you mean "sonata.news.admin.post" or one of those: [sonata.news.admin.category]?');
196
197
        $this->pool->getInstance('sonata.news.admin.pos');
198
    }
199
200
    public function testGetAdminByAdminCode(): void
201
    {
202
        $this->container->set('sonata.news.admin.post', $this->createMock(AdminInterface::class));
203
204
        $this->pool->setAdminServiceIds(['sonata.news.admin.post']);
205
206
        $this->assertInstanceOf(AdminInterface::class, $this->pool->getAdminByAdminCode('sonata.news.admin.post'));
207
    }
208
209
    public function testGetAdminByAdminCodeForChildClass(): void
210
    {
211
        $adminMock = $this->createMock(AdminInterface::class);
212
        $adminMock
213
            ->method('hasChild')
214
            ->willReturn(true);
215
216
        $childAdmin = $this->createMock(AdminInterface::class);
217
218
        $adminMock->expects($this->once())
219
            ->method('getChild')
220
            ->with($this->equalTo('sonata.news.admin.comment'))
221
            ->willReturn($childAdmin);
222
223
        $this->container->set('sonata.news.admin.post', $adminMock);
224
225
        $this->pool->setAdminServiceIds(['sonata.news.admin.post', 'sonata.news.admin.comment']);
226
227
        $this->assertSame($childAdmin, $this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.comment'));
228
    }
229
230
    public function testGetAdminByAdminCodeWithInvalidCode(): void
231
    {
232
        $adminMock = $this->createMock(AdminInterface::class);
233
        $adminMock
234
            ->method('hasChild')
235
            ->willReturn(false);
236
237
        $this->container->set('sonata.news.admin.post', $adminMock);
238
        $this->pool->setAdminServiceIds(['sonata.news.admin.post']);
239
240
        $this->expectException(\InvalidArgumentException::class);
241
        $this->expectExceptionMessage('Argument 1 passed to Sonata\AdminBundle\Admin\Pool::getAdminByAdminCode() must contain a valid admin reference, "sonata.news.admin.invalid" found at "sonata.news.admin.post|sonata.news.admin.invalid".');
242
243
        $this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.invalid');
244
    }
245
246
    public function testGetAdminByAdminCodeWithCodeNotChild(): void
247
    {
248
        $adminMock = $this->getMockBuilder(AdminInterface::class)
249
            ->disableOriginalConstructor()
250
            ->getMock();
251
        $adminMock->expects($this->any())
252
            ->method('hasChild')
253
            ->willReturn(false);
254
255
        $containerMock = $this->createMock(ContainerInterface::class);
256
        $containerMock->expects($this->any())
257
            ->method('get')
258
            ->willReturn($adminMock);
259
260
        $this->pool = new Pool($containerMock, 'Sonata', '/path/to/logo.png');
261
        $this->pool->setAdminServiceIds(['sonata.news.admin.post', 'sonata.news.admin.valid']);
262
263
        $this->expectException(\InvalidArgumentException::class);
264
        $this->pool->getAdminByAdminCode('sonata.news.admin.post|sonata.news.admin.valid');
265
    }
266
267
    /**
268
     * @dataProvider getNonStringAdminServiceNames
269
     */
270
    public function testGetAdminByAdminCodeWithNonStringCode($adminId): void
271
    {
272
        $this->expectException(\TypeError::class);
273
274
        $this->pool->getAdminByAdminCode($adminId);
275
    }
276
277
    public function getNonStringAdminServiceNames(): array
278
    {
279
        return [
280
            [null],
281
            [false],
282
            [1],
283
            [['some_value']],
284
            [new \stdClass()],
285
        ];
286
    }
287
288
    /**
289
     * @dataProvider getEmptyRootAdminServiceNames
290
     */
291
    public function testGetAdminByAdminCodeWithInvalidRootCode(string $adminId): void
292
    {
293
        $adminMock = $this->createMock(AdminInterface::class);
294
        $adminMock->expects($this->never())
295
            ->method('hasChild');
296
297
        /** @var MockObject|Pool $poolMock */
298
        $poolMock = $this->getMockBuilder(Pool::class)
299
            ->setConstructorArgs([$this->container, 'Sonata', '/path/to/logo.png'])
300
            ->disableOriginalClone()
301
            ->setMethodsExcept(['getAdminByAdminCode'])
302
            ->getMock();
303
        $poolMock->expects($this->never())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\Pool>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
304
            ->method('getInstance');
305
306
        $this->expectException(\InvalidArgumentException::class);
307
        $this->expectExceptionMessage('Root admin code must contain a valid admin reference, empty string given.');
308
        $poolMock->getAdminByAdminCode($adminId);
309
    }
310
311
    public function getEmptyRootAdminServiceNames()
312
    {
313
        return [
314
            [''],
315
            ['   '],
316
            ['|sonata.news.admin.child_of_empty_code'],
317
        ];
318
    }
319
320
    /**
321
     * @dataProvider getInvalidChildAdminServiceNames
322
     */
323
    public function testGetAdminByAdminCodeWithInvalidChildCode(string $adminId): void
324
    {
325
        $adminMock = $this->createMock(AdminInterface::class);
326
        $adminMock
327
            ->method('hasChild')
328
            ->willReturn(false);
329
        $adminMock->expects($this->never())
330
            ->method('getChild');
331
332
        /** @var MockObject|Pool $poolMock */
333
        $poolMock = $this->getMockBuilder(Pool::class)
334
            ->setConstructorArgs([$this->container, 'Sonata', '/path/to/logo.png'])
335
            ->disableOriginalClone()
336
            ->setMethodsExcept(['getAdminByAdminCode'])
337
            ->getMock();
338
        $poolMock
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Sonata\AdminBundle\Admin\Pool>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
339
            ->method('getInstance')
340
            ->willReturn($adminMock);
341
342
        $this->expectException(\InvalidArgumentException::class);
343
        $this->expectExceptionMessageRegExp(sprintf(
344
            '{^Argument 1 passed to Sonata\\\AdminBundle\\\Admin\\\Pool::getAdminByAdminCode\(\) must contain a valid admin reference, "[^"]+" found at "%s"\.$}',
345
            $adminId
346
        ));
347
348
        $poolMock->getAdminByAdminCode($adminId);
349
    }
350
351
    public function getInvalidChildAdminServiceNames()
352
    {
353
        return [
354
            ['admin1|'],
355
            ['admin1|nonexistent_code'],
356
            ['admin1||admin3'],
357
        ];
358
    }
359
360
    /**
361
     * @dataProvider getAdminServiceNamesToCheck
362
     */
363
    public function testHasAdminByAdminCode(string $adminId): void
364
    {
365
        $adminMock = $this->createMock(AdminInterface::class);
366
367
        if (false !== strpos($adminId, '|')) {
368
            $childAdminMock = $this->createMock(AdminInterface::class);
369
            $adminMock
370
                ->method('hasChild')
371
                ->willReturn(true);
372
            $adminMock->expects($this->once())
373
                ->method('getChild')
374
                ->with($this->equalTo('sonata.news.admin.comment'))
375
                ->willReturn($childAdminMock);
376
        } else {
377
            $adminMock->expects($this->never())
378
                ->method('hasChild');
379
            $adminMock->expects($this->never())
380
                ->method('getChild');
381
        }
382
383
        $this->container->set('sonata.news.admin.post', $adminMock);
384
385
        $this->pool->setAdminServiceIds(['sonata.news.admin.post', 'sonata.news.admin.comment']);
386
387
        $this->assertTrue($this->pool->hasAdminByAdminCode($adminId));
388
    }
389
390
    public function getAdminServiceNamesToCheck()
391
    {
392
        return [
393
            ['sonata.news.admin.post'],
394
            ['sonata.news.admin.post|sonata.news.admin.comment'],
395
        ];
396
    }
397
398
    /**
399
     * @dataProvider getNonStringAdminServiceNames
400
     */
401
    public function testHasAdminByAdminCodeWithNonStringCode($adminId): void
402
    {
403
        $this->expectException(\TypeError::class);
404
        $this->pool->hasAdminByAdminCode($adminId);
405
    }
406
407
    /**
408
     * @dataProvider getInvalidAdminServiceNamesToCheck
409
     */
410
    public function testHasAdminByAdminCodeWithInvalidCodes(string $adminId): void
411
    {
412
        $adminMock = $this->createMock(AdminInterface::class);
413
        $adminMock
414
            ->method('hasChild')
415
            ->willReturn(false);
416
        $adminMock->expects($this->never())
417
            ->method('getChild');
418
419
        $this->assertFalse($this->pool->hasAdminByAdminCode($adminId));
420
    }
421
422
    public function getInvalidAdminServiceNamesToCheck()
423
    {
424
        return [
425
            [''],
426
            ['   '],
427
            ['|sonata.news.admin.child_of_empty_code'],
428
        ];
429
    }
430
431
    public function testHasAdminByAdminCodeWithNonExistentCode(): void
432
    {
433
        $this->assertFalse($this->pool->hasAdminByAdminCode('sonata.news.admin.nonexistent_code'));
434
    }
435
436
    /**
437
     * @dataProvider getInvalidChildAdminServiceNamesToCheck
438
     */
439
    public function testHasAdminByAdminCodeWithInvalidChildCodes(string $adminId): void
440
    {
441
        $adminMock = $this->createMock(AdminInterface::class);
442
        $adminMock
443
            ->method('hasChild')
444
            ->willReturn(false);
445
        $adminMock->expects($this->never())
446
            ->method('getChild');
447
448
        $this->container->set('sonata.news.admin.post', $adminMock);
449
450
        $this->pool->setAdminServiceIds(['sonata.news.admin.post']);
451
452
        $this->assertFalse($this->pool->hasAdminByAdminCode($adminId));
453
    }
454
455
    public function getInvalidChildAdminServiceNamesToCheck(): array
456
    {
457
        return [
458
            ['sonata.news.admin.post|'],
459
            ['sonata.news.admin.post|nonexistent_code'],
460
            ['sonata.news.admin.post||admin3'],
461
        ];
462
    }
463
464
    public function testGetAdminClasses(): void
465
    {
466
        $this->pool->setAdminClasses(['someclass' => 'sonata.user.admin.group1']);
467
        $this->assertSame(['someclass' => 'sonata.user.admin.group1'], $this->pool->getAdminClasses());
468
    }
469
470
    public function testGetAdminGroups(): void
471
    {
472
        $this->pool->setAdminGroups(['adminGroup1' => 'sonata.user.admin.group1']);
473
        $this->assertSame(['adminGroup1' => 'sonata.user.admin.group1'], $this->pool->getAdminGroups());
474
    }
475
476
    public function testGetAdminServiceIds(): void
477
    {
478
        $this->pool->setAdminServiceIds(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3']);
479
        $this->assertSame(['sonata.user.admin.group1', 'sonata.user.admin.group2', 'sonata.user.admin.group3'], $this->pool->getAdminServiceIds());
480
    }
481
482
    public function testGetContainer(): void
483
    {
484
        $this->assertInstanceOf(ContainerInterface::class, $this->pool->getContainer());
485
    }
486
487
    public function testGetTitleLogo(): void
488
    {
489
        $this->assertSame('/path/to/pic.png', $this->pool->getTitleLogo());
490
    }
491
492
    public function testGetTitle(): void
493
    {
494
        $this->assertSame('Sonata Admin', $this->pool->getTitle());
495
    }
496
497
    public function testGetOption(): void
498
    {
499
        $this->assertSame('bar', $this->pool->getOption('foo'));
500
501
        $this->assertNull($this->pool->getOption('non_existent_option'));
502
    }
503
504
    public function testOptionDefault(): void
505
    {
506
        $this->assertSame([], $this->pool->getOption('nonexistantarray', []));
507
    }
508
509
    private function getItemArray(string $serviceId): array
510
    {
511
        return [
512
            'admin' => $serviceId,
513
            'label' => '',
514
            'route' => '',
515
            'route_params' => [],
516
        ];
517
    }
518
}
519