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
|
|
|
/** |
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'); |
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')); |
|
|
|
|
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); |
|
|
|
|
387
|
|
|
|
388
|
|
|
$this->assertSame($templates, $this->pool->getTemplates()); |
|
|
|
|
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
|
|
|
|
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.