Completed
Push — master ( 3e4cf7...14abe7 )
by Jeroen
07:38 queued 12s
created

Security/Acl/Permission/PermissionAdminTest.php (5 issues)

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
namespace Kunstmaan\AdminBundle\Tests\Helper\Security\Acl\Permission;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\EntityRepository;
8
use Kunstmaan\AdminBundle\Entity\AbstractEntity;
9
use Kunstmaan\AdminBundle\Entity\Role;
10
use Kunstmaan\AdminBundle\Entity\User;
11
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\MaskBuilder;
12
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionAdmin;
13
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMapInterface;
14
use Kunstmaan\NodeBundle\Entity\Node;
15
use Kunstmaan\UtilitiesBundle\Helper\Shell\Shell;
16
use PHPUnit\Framework\TestCase;
17
use ReflectionClass;
18
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpKernel\Kernel;
21
use Symfony\Component\HttpKernel\KernelInterface;
22
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
23
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
24
use Symfony\Component\Security\Acl\Model\AclInterface;
25
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
26
use Symfony\Component\Security\Acl\Model\AuditableEntryInterface;
27
use Symfony\Component\Security\Acl\Model\MutableAclInterface;
28
use Symfony\Component\Security\Acl\Model\MutableAclProviderInterface;
29
use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
30
use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
31
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
32
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
33
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
34
35
class PermissionAdminTest extends TestCase
36
{
37
    /**
38
     * @var PermissionAdmin
39
     */
40
    protected $object;
41
42
    public function testInitialize()
43
    {
44
        $object = $this->getInitializedPermissionAdmin();
45
        $this->assertEquals(array('ROLE_TEST' => new MaskBuilder(1)), $object->getPermissions());
46
    }
47
48
    public function testGetPermissionWithString()
49
    {
50
        $object = $this->getInitializedPermissionAdmin();
51
        $this->assertEquals(new MaskBuilder(1), $object->getPermission('ROLE_TEST'));
52
    }
53
54
    public function testGetPermissionWithRoleObject()
55
    {
56
        $object = $this->getInitializedPermissionAdmin();
57
58
        $role = $this->createMock('Symfony\Component\Security\Core\Role\Role');
59
        $role->expects($this->once())
60
            ->method('getRole')
61
            ->will($this->returnValue('ROLE_TEST'));
62
        $this->assertEquals(new MaskBuilder(1), $object->getPermission($role));
63
    }
64
65
    public function testGetPermissionWithUnknownRole()
66
    {
67
        $object = $this->getInitializedPermissionAdmin();
68
        $this->assertNull($object->getPermission('ROLE_UNKNOWN'));
69
    }
70
71
    public function testGetAllRoles()
72
    {
73
        $roleRepo = $this->getMockBuilder('Doctrine\ORM\EntityRepository')
74
            ->disableOriginalConstructor()
75
            ->getMock();
76
        $roleRepo->expects($this->once())
77
            ->method('findAll')
78
            ->will($this->returnValue(null));
79
80
        $em = $this->getEntityManager();
81
        $em->expects($this->once())
82
            ->method('getRepository')
83
            ->with(Role::class)
84
            ->will($this->returnValue($roleRepo));
85
        $context = $this->getTokenStorage();
86
        $aclProvider = $this->getAclProvider();
87
        $retrievalStrategy = $this->getOidRetrievalStrategy();
88
        $dispatcher = $this->getEventDispatcher();
89
        $shell = $this->getShell();
90
        $kernel = $this->getKernel();
91
        $object = new PermissionAdmin($em, $context, $aclProvider, $retrievalStrategy, $dispatcher, $shell, $kernel);
0 ignored issues
show
$shell is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Kunstmaan\Utiliti...dle\Helper\Shell\Shell>.

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
93
        $this->assertNull($object->getAllRoles());
94
    }
95
96
    public function testGetPossiblePermissions()
97
    {
98
        $em = $this->getEntityManager();
99
        $context = $this->getTokenStorage();
100
        $aclProvider = $this->getAclProvider();
101
        $retrievalStrategy = $this->getOidRetrievalStrategy();
102
        $retrievalStrategy
103
            ->expects($this->once())
104
            ->method('getObjectIdentity')
105
            ->will($this->throwException(new \Symfony\Component\Security\Acl\Exception\AclNotFoundException()));
106
        $dispatcher = $this->getEventDispatcher();
107
        $shell = $this->getShell();
108
        $kernel = $this->getKernel();
109
        $object = new PermissionAdmin($em, $context, $aclProvider, $retrievalStrategy, $dispatcher, $shell, $kernel);
0 ignored issues
show
$shell is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Kunstmaan\Utiliti...dle\Helper\Shell\Shell>.

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...
110
111
        $permissions = array('PERMISSION1', 'PERMISSION2');
112
        $permissionMap = $this->createMock('Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMapInterface');
113
        $permissionMap
114
            ->expects($this->any())
115
            ->method('getPossiblePermissions')
116
            ->will($this->returnValue($permissions));
117
        $entity = $this->getEntity();
118
        /* @var $permissionMap PermissionMapInterface */
119
        $object->initialize($entity, $permissionMap);
120
        $this->assertEquals($permissions, $object->getPossiblePermissions());
121
    }
122
123
    public function testCreateAclChangeset()
124
    {
125
        $em = $this->getEntityManager();
126
        $em->expects($this->once())
127
            ->method('persist')
128
            ->with($this->isInstanceOf('Kunstmaan\AdminBundle\Entity\AclChangeset'));
129
        $em->expects($this->once())
130
            ->method('flush');
131
        $context = $this->getTokenStorage();
132
        $aclProvider = $this->getAclProvider();
133
        $retrievalStrategy = $this->getOidRetrievalStrategy();
134
        $dispatcher = $this->getEventDispatcher();
135
        $shell = $this->getShell();
136
        $kernel = $this->getKernel();
137
        $object = new PermissionAdmin($em, $context, $aclProvider, $retrievalStrategy, $dispatcher, $shell, $kernel);
0 ignored issues
show
$shell is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Kunstmaan\Utiliti...dle\Helper\Shell\Shell>.

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...
138
139
        $entity = $this->getEntity();
140
        /* @var $user User */
141
        $user = $this->getMockBuilder('Kunstmaan\AdminBundle\Entity\User')
142
            ->disableOriginalConstructor()
143
            ->getMock();
144
145
        $object->createAclChangeSet($entity, array(), $user);
146
    }
147
148
    /**
149
     * Return entity manager mock
150
     *
151
     * @return EntityManager
152
     */
153
    public function getEntityManager()
154
    {
155
        return $this->getMockBuilder('Doctrine\ORM\EntityManager')
156
            ->disableOriginalConstructor()
157
            ->getMock();
158
    }
159
160
    /**
161
     * Return alc provider mock
162
     *
163
     * @return AclProviderInterface
164
     */
165
    public function getAclProvider()
166
    {
167
        return $this->createMock('Symfony\Component\Security\Acl\Model\MutableAclProviderInterface');
168
    }
169
170
    /**
171
     * Return security token storage
172
     *
173
     * @return TokenStorageInterface
174
     */
175
    public function getTokenStorage()
176
    {
177
        return $this->createMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
178
    }
179
180
    /**
181
     * Return oid retrieval strategy mock
182
     *
183
     * @return ObjectIdentityRetrievalStrategyInterface
184
     */
185
    public function getOidRetrievalStrategy()
186
    {
187
        return $this->createMock('Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface');
188
    }
189
190
    /**
191
     * Return event dispatcher mock
192
     *
193
     * @return EventDispatcherInterface
194
     */
195
    public function getEventDispatcher()
196
    {
197
        return $this->createMock('Symfony\Component\EventDispatcher\EventDispatcher');
198
    }
199
200
    /**
201
     * @return Shell
0 ignored issues
show
Should the return type not be \PHPUnit\Framework\MockObject\MockObject?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
202
     */
203
    public function getShell()
204
    {
205
        $mock = $this->createMock(Shell::class);
206
        $mock->method('runInBackground')
207
            ->with('php /some/project/directory/bin/console kuma:acl:apply --env=test')
208
        ;
209
210
        return $mock;
211
    }
212
213
    /**
214
     * @return KernelInterface
215
     */
216
    public function getKernel()
217
    {
218
        $mock = $this->createMock(Kernel::class);
219
        $mock->method('getProjectDir')->willReturn('/some/project/directory');
220
        $mock->method('getEnvironment')->willReturn('test');
221
222
        return $mock;
223
    }
224
225
    /**
226
     * Return permission admin mock
227
     *
228
     * @return PermissionAdmin
229
     */
230
    public function getPermissionAdmin()
231
    {
232
        $em = $this->getEntityManager();
233
        $context = $this->getTokenStorage();
234
235
        $securityIdentity = new RoleSecurityIdentity('ROLE_TEST');
236
237
        $entity = $this->getMockBuilder('Symfony\Component\Security\Acl\Domain\Entry')
238
            ->disableOriginalConstructor()
239
            ->getMock();
240
        $entity
241
            ->expects($this->any())
242
            ->method('getSecurityIdentity')
243
            ->will($this->returnValue($securityIdentity));
244
        $entity
245
            ->expects($this->any())
246
            ->method('getMask')
247
            ->will($this->returnValue(1));
248
249
        $acl = $this->getMockBuilder('Symfony\Component\Security\Acl\Domain\Acl')
250
            ->disableOriginalConstructor()
251
            ->getMock();
252
        $acl->expects($this->atLeastOnce())
253
            ->method('getObjectAces')
254
            ->will($this->returnValue(array($entity)));
255
256
        $aclProvider = $this->getAclProvider();
257
        $aclProvider
258
            ->expects($this->atLeastOnce())
259
            ->method('findAcl')
260
            ->with($this->anything())
261
            ->will($this->returnValue($acl));
262
263
        $retrievalStrategy = $this->getOidRetrievalStrategy();
264
        $objectIdentity = $this->createMock('Symfony\Component\Security\Acl\Model\ObjectIdentityInterface');
265
        $retrievalStrategy
266
            ->expects($this->atLeastOnce())
267
            ->method('getObjectIdentity')
268
            ->will($this->returnValue($objectIdentity));
269
        $dispatcher = $this->getEventDispatcher();
270
        $shell = $this->getShell();
271
        $kernel = $this->getKernel();
272
        $object = new PermissionAdmin($em, $context, $aclProvider, $retrievalStrategy, $dispatcher, $shell, $kernel);
0 ignored issues
show
$shell is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Kunstmaan\Utiliti...dle\Helper\Shell\Shell>.

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...
273
274
        return $object;
275
    }
276
277
    /**
278
     * Return entity mock
279
     *
280
     * @return AbstractEntity
281
     */
282
    public function getEntity()
283
    {
284
        return $this->getMockForAbstractClass('Kunstmaan\AdminBundle\Entity\AbstractEntity');
285
    }
286
287
    /**
288
     * Return permission admin mock
289
     *
290
     * @return PermissionAdmin
291
     */
292
    public function getInitializedPermissionAdmin()
293
    {
294
        $object = $this->getPermissionAdmin();
295
        $entity = $this->getEntity();
296
        /* @var $permissionMap PermissionMapInterface */
297
        $permissionMap = $this->createMock('Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMapInterface');
298
        $object->initialize($entity, $permissionMap);
299
300
        return $object;
301
    }
302
303
    public function testBindRequestReturnsTrueWhenNoChanges()
304
    {
305
        $object = $this->getInitializedPermissionAdmin();
306
        $request = $this->createMock(Request::class);
307
        $request->request = $this->createMock(Request::class);
308
        $request->request->expects($this->once())->method('get')->willReturn('');
309
        $object->bindRequest($request);
310
    }
311
312
    /**
313
     * @throws \ReflectionException
314
     */
315
    public function testBindRequest()
316
    {
317
        $object = $this->getInitializedPermissionAdmin();
318
        $token = $this->createMock(PreAuthenticatedToken::class);
319
        $token->expects($this->once())->method('getUser')->willReturn(new User());
320
        $request = $this->createMock(Request::class);
321
        $request->request = $this->createMock(Request::class);
322
        $request->request->expects($this->any())->method('get')->will($this->onConsecutiveCalls(['ADMIN' => ['ADD' => ['VIEW']]], true));
323
324
        $mirror = new ReflectionClass(PermissionAdmin::class);
325
        $property = $mirror->getProperty('tokenStorage');
326
        $property->setAccessible(true);
327
        $val = $property->getValue($object);
328
        $val->expects($this->once())->method('getToken')->willReturn($token);
329
330
        $object->bindRequest($request);
331
    }
332
333
    /**
334
     * @throws \ReflectionException
335
     */
336
    public function testMaskAtIndex()
337
    {
338
        $object = $this->getInitializedPermissionAdmin();
339
340
        $id = $this->createMock(SecurityIdentityInterface::class);
341
        $ace = $this->createMock(AuditableEntryInterface::class);
342
        $ace->expects($this->once())->method('getSecurityIdentity')->willReturn($id);
343
        $acl = $this->createMock(AclInterface::class);
344
        $acl->expects($this->once())->method('getObjectAces')->willReturn([1 => $ace]);
345
346
        $mirror = new ReflectionClass(PermissionAdmin::class);
347
        $method = $mirror->getMethod('getMaskAtIndex');
348
        $method->setAccessible(true);
349
350
        $this->assertFalse($method->invoke($object, $acl, 1));
351
352
        $id = new RoleSecurityIdentity('ADMIN');
353
        $ace = $this->createMock(AuditableEntryInterface::class);
354
        $ace->expects($this->once())->method('getSecurityIdentity')->willReturn($id);
355
        $ace->expects($this->once())->method('getMask')->willReturn(true);
356
        $acl = $this->createMock(AclInterface::class);
357
        $acl->expects($this->once())->method('getObjectAces')->willReturn([1 => $ace]);
358
359
        $this->assertTrue($method->invoke($object, $acl, 1));
360
    }
361
362
    /**
363
     * @throws \ReflectionException
364
     */
365
    public function testGetManageableRolesForPages()
366
    {
367
        $object = $this->getInitializedPermissionAdmin();
368
369
        $repo = $this->createMock(EntityRepository::class);
370
        $repo->expects($this->once())->method('findAll')->willReturn(['ROLE_SUPER_ADMIN', 'USER']);
371
372
        $em = $this->getEntityManager();
373
        $em->expects($this->once())->method('getRepository')->willReturn($repo);
374
375
        $token = $this->createMock(PreAuthenticatedToken::class);
376
        $token->expects($this->once())->method('getUser')->willReturn(new User());
377
378
        $storage = $this->createMock(TokenStorage::class);
379
        $storage->expects($this->once())->method('getToken')->willReturn($token);
380
381
        $mirror = new ReflectionClass(PermissionAdmin::class);
382
        $property = $mirror->getProperty('tokenStorage');
383
        $property->setAccessible(true);
384
        $property->setValue($object, $storage);
385
        $property = $mirror->getProperty('em');
386
        $property->setAccessible(true);
387
        $property->setValue($object, $em);
388
389
        $roles = $object->getManageableRolesForPages();
390
        $this->assertCount(1, $roles);
391
        $this->assertTrue(\in_array('USER', $roles));
392
    }
393
394
    /**
395
     * @throws \ReflectionException
396
     */
397
    public function testApplyAclChangesetReturnsNull()
398
    {
399
        $object = $this->getInitializedPermissionAdmin();
400
        $entity = $this->createMock(AbstractEntity::class);
401
        $entity->method('getId')->willReturn(666);
402
        $entity->method('setId')->willReturn(null);
403
        $entity->method('__toString')->willReturn('666');
404
405
        $this->assertNull($object->applyAclChangeset($entity, [], true));
406
    }
407
408
    /**
409
     * @throws \ReflectionException
410
     */
411
    public function testApplyAclAppliesChangesetRecursive()
412
    {
413
        $object = $this->getInitializedPermissionAdmin();
414
        $acl = $this->createMock(MutableAclInterface::class);
415
        $provider = $this->createMock(MutableAclProviderInterface::class);
416
        $provider->expects($this->atLeastOnce())->method('findAcl')->willThrowException(new AclNotFoundException());
417
        $provider->expects($this->atLeastOnce())->method('createAcl')->willReturn($acl);
418
419
        $mirror = new ReflectionClass(PermissionAdmin::class);
420
        $property = $mirror->getProperty('aclProvider');
421
        $property->setAccessible(true);
422
        $property->setValue($object, $provider);
423
424
        $entity = new Node();
425
        $entity->setChildren(new ArrayCollection([new Node()]));
426
        $this->assertNull($object->applyAclChangeset($entity, [], true));
427
    }
428
429
    /**
430
     * @throws \ReflectionException
431
     */
432
    public function testApplyAclAppliesChangeset()
433
    {
434
        $object = $this->getInitializedPermissionAdmin();
435
436
        $entity = new Node();
437
        $this->assertNull($object->applyAclChangeset($entity, ['ROLE_TEST' => ['DEL' => ['VIEW']]], false));
438
    }
439
}
440