Completed
Push — master ( ae5e03...0447ee )
by Jeroen
10:35 queued 04:37
created

Tests/unit/Helper/Security/Acl/AclHelperTest.php (23 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;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Driver\Statement;
7
use Doctrine\DBAL\Platforms\AbstractPlatform;
8
use Doctrine\ORM\Configuration;
9
use Doctrine\ORM\EntityManager;
10
use Doctrine\ORM\Mapping\ClassMetadata;
11
use Doctrine\ORM\Mapping\QuoteStrategy;
12
use Doctrine\ORM\NativeQuery;
13
use Doctrine\ORM\Query;
14
use Doctrine\ORM\QueryBuilder;
15
use FOS\UserBundle\Model\UserInterface;
16
use Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper;
17
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\MaskBuilder;
18
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionDefinition;
19
use PHPUnit\Framework\TestCase;
20
use Symfony\Component\HttpKernel\Kernel;
21
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
22
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
23
use Symfony\Component\Security\Core\Role\Role;
24
use Symfony\Component\Security\Core\Role\RoleHierarchy;
25
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
26
27
class AclHelperTest extends TestCase
28
{
29
    /**
30
     * @var EntityManager
31
     */
32
    protected $em;
33
34
    /**
35
     * @var TokenStorageInterface
36
     */
37
    protected $tokenStorage;
38
39
    /**
40
     * @var RoleHierarchyInterface
41
     */
42
    protected $rh;
43
44
    /**
45
     * @var TokenInterface
46
     */
47
    protected $token;
48
49
    /**
50
     * @var UserInterface
51
     */
52
    protected $user;
53
54
    /**
55
     * @var AclHelper
56
     */
57
    protected $object;
58
59
    /**
60
     * Sets up the fixture, for example, opens a network connection.
61
     * This method is called before a test is executed.
62
     */
63
    protected function setUp()
64
    {
65
        $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getMockBuilder('D...onstructor()->getMock() of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Doctrine\ORM\EntityManager> of property $em.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
66
            ->disableOriginalConstructor()
67
            ->getMock();
68
69
        /* @var $conn Connection */
70
        $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
71
            ->disableOriginalConstructor()
72
            ->getMock();
73
74
        $conn->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\DBAL\Connection>.

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...
75
            ->method('getDatabase')
76
            ->will($this->returnValue('myDatabase'));
77
78
        /* @var $platform AbstractPlatform */
79
        $platform = $this->getMockForAbstractClass('Doctrine\DBAL\Platforms\AbstractPlatform');
80
81
        $conn->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\DBAL\Connection>.

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...
82
            ->method('getDatabasePlatform')
83
            ->will($this->returnValue($platform));
84
85
        /* @var $stmt Statement */
86
        $stmt = $this->createMock(Statement::class);
87
88
        $conn->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\DBAL\Connection>.

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...
89
            ->method('executeQuery')
90
            ->will($this->returnValue($stmt));
91
92
        $this->em->expects($this->any())
93
            ->method('getConnection')
94
            ->will($this->returnValue($conn));
95
96
        /* @var $conf Configuration */
97
        $conf = $this->getMockBuilder('Doctrine\ORM\Configuration')
98
            ->disableOriginalConstructor()
99
            ->getMock();
100
101
        /* @var $strat QuoteStrategy */
102
        $strat = $this->getMockBuilder('Doctrine\ORM\Mapping\QuoteStrategy')
103
            ->disableOriginalConstructor()
104
            ->getMock();
105
106
        $strat->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\Mapping\QuoteStrategy>.

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...
107
            ->method('getTableName')
108
            ->will($this->returnValue('rootTable'));
109
110
        $conf->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\Configuration>.

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...
111
            ->method('getQuoteStrategy')
112
            ->will($this->returnValue($strat));
113
114
        $conf->expects($this->any())
115
            ->method('getDefaultQueryHints')
116
            ->willReturn(array());
117
118
        $conf->expects($this->any())
119
            ->method('isSecondLevelCacheEnabled')
120
            ->willReturn(false);
121
122
        $this->em->expects($this->any())
123
            ->method('getConfiguration')
124
            ->will($this->returnValue($conf));
125
126
        /* @var $meta ClassMetadata */
127
        $meta = $this->getMockBuilder('Doctrine\ORM\Mapping\ClassMetadata')
128
            ->disableOriginalConstructor()
129
            ->getMock();
130
131
        $this->em->expects($this->any())
132
            ->method('getClassMetadata')
133
            ->will($this->returnValue($meta));
134
135
        $this->tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')
136
            ->getMock();
137
138
        $this->token = $this->createMock('Symfony\Component\Security\Core\Authentication\Token\AbstractToken');
139
140
        $this->tokenStorage->expects($this->any())
141
            ->method('getToken')
142
            ->will($this->returnValue($this->token));
143
144
        $this->rh = $this->getMockBuilder(RoleHierarchy::class)
145
            ->disableOriginalConstructor()
146
            ->getMock();
147
148
        $this->object = new AclHelper($this->em, $this->tokenStorage, $this->rh);
149
    }
150
151
    public function testApply()
152
    {
153
        /* @var $queryBuilder QueryBuilder */
154
        $queryBuilder = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
155
            ->disableOriginalConstructor()
156
            ->getMock();
157
158
        $query = new Query($this->em);
159
        $query->setParameter('paramName', 'paramValue', 'paramType');
160
        $queryBuilder->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\QueryBuilder>.

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...
161
            ->method('getQuery')
162
            ->will($this->returnValue($query));
163
164
        $queryBuilder->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\QueryBuilder>.

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...
165
            ->method('getRootEntities')
166
            ->will($this->returnValue(array('Kunstmaan\NodeBundle\Entity\Node')));
167
168
        $queryBuilder->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\QueryBuilder>.

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...
169
            ->method('getRootAliases')
170
            ->will($this->returnValue(array('n')));
171
172
        $user = $this->getMockBuilder('FOS\UserBundle\Model\UserInterface')
173
            ->getMock();
174
175
        $user->expects($this->any())
176
            ->method('getUsername')
177
            ->will($this->returnValue('MyUser'));
178
179
        $this->token->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...n\Token\TokenInterface>.

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...
180
            ->method('getUser')
181
            ->will($this->returnValue($user));
182
183
        [$rolesMethodName, $roles, $reachableRolesMethodName, $allRoles,] = $this->getRoleMockData();
184
185
        $this->token->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...n\Token\TokenInterface>.

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...
186
            ->method($rolesMethodName)
187
            ->will($this->returnValue($roles));
188
189
        $this->rh->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...RoleHierarchyInterface>.

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...
190
            ->method($reachableRolesMethodName)
191
            ->with($roles)
192
            ->will($this->returnValue($allRoles));
193
194
        $permissionDef = new PermissionDefinition(array('view'), 'Kunstmaan\NodeBundle\Entity\Node');
195
196
        /* @var $query Query */
197
        $query = $this->object->apply($queryBuilder, $permissionDef);
198
199
        $this->assertEquals(MaskBuilder::MASK_VIEW, $query->getHint('acl.mask'));
200
        $this->assertEquals($permissionDef->getEntity(), $query->getHint('acl.root.entity'));
201
        $this->assertEquals('rootTable', $query->getHint('acl.entityRootTableName'));
202
        $this->assertEquals('n', $query->getHint('acl.entityRootTableDqlAlias'));
203
204
        $aclQuery = $query->getHint('acl.extra.query');
205
        $this->assertContains('"ROLE_SUBJECT"', $aclQuery);
206
        $this->assertContains('"ROLE_KING"', $aclQuery);
207
        $this->assertContains('"IS_AUTHENTICATED_ANONYMOUSLY"', $aclQuery);
208
        $this->assertContains('MyUser', $aclQuery);
209
    }
210
211
    public function testApplyAnonymous()
212
    {
213
        /* @var $queryBuilder QueryBuilder */
214
        $queryBuilder = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
215
            ->disableOriginalConstructor()
216
            ->getMock();
217
218
        $query = new Query($this->em);
219
        $query->setParameter('paramName', 'paramValue', 'paramType');
220
        $queryBuilder->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\QueryBuilder>.

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...
221
            ->method('getQuery')
222
            ->will($this->returnValue($query));
223
224
        $queryBuilder->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\QueryBuilder>.

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...
225
            ->method('getRootEntities')
226
            ->will($this->returnValue(array('Kunstmaan\NodeBundle\Entity\Node')));
227
228
        $queryBuilder->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\QueryBuilder>.

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...
229
            ->method('getRootAliases')
230
            ->will($this->returnValue(array('n')));
231
232
        [$rolesMethodName, $roles, $reachableRolesMethodName, $allRoles,] = $this->getRoleMockData(true);
233
234
        $this->token->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...n\Token\TokenInterface>.

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...
235
            ->method($rolesMethodName)
236
            ->will($this->returnValue($roles));
237
238
        $this->rh->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...RoleHierarchyInterface>.

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...
239
            ->method($reachableRolesMethodName)
240
            ->with($roles)
241
            ->will($this->returnValue($allRoles));
242
243
        $this->token->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...n\Token\TokenInterface>.

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...
244
            ->method('getUser')
245
            ->will($this->returnValue('anon.'));
246
247
        $permissionDef = new PermissionDefinition(array('view'), 'Kunstmaan\NodeBundle\Entity\Node');
248
249
        /* @var $query Query */
250
        $query = $this->object->apply($queryBuilder, $permissionDef);
251
252
        $this->assertEquals(MaskBuilder::MASK_VIEW, $query->getHint('acl.mask'));
253
        $this->assertEquals($permissionDef->getEntity(), $query->getHint('acl.root.entity'));
254
        $this->assertEquals('rootTable', $query->getHint('acl.entityRootTableName'));
255
        $this->assertEquals('n', $query->getHint('acl.entityRootTableDqlAlias'));
256
257
        $aclQuery = $query->getHint('acl.extra.query');
258
        $this->assertContains('"IS_AUTHENTICATED_ANONYMOUSLY"', $aclQuery);
259
    }
260
261
    public function testGetAllowedEntityIds()
262
    {
263
        [$rolesMethodName, $roles, $reachableRolesMethodName, $allRoles,] = $this->getRoleMockData();
264
265
        $this->token->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...n\Token\TokenInterface>.

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...
266
            ->method($rolesMethodName)
267
            ->will($this->returnValue($roles));
268
269
        $this->rh->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...RoleHierarchyInterface>.

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...
270
            ->method($reachableRolesMethodName)
271
            ->with($roles)
272
            ->will($this->returnValue($allRoles));
273
274
        $user = $this->getMockBuilder('FOS\UserBundle\Model\UserInterface')
275
            ->getMock();
276
277
        $user->expects($this->any())
278
            ->method('getUsername')
279
            ->will($this->returnValue('MyUser'));
280
281
        $this->token->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Symfony\Component...n\Token\TokenInterface>.

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...
282
            ->method('getUser')
283
            ->will($this->returnValue($user));
284
285
        $hydrator = $this->getMockBuilder('Doctrine\ORM\Internal\Hydration\ScalarHydrator')
286
            ->disableOriginalConstructor()
287
            ->getMock();
288
289
        $rows = array(
290
            array('id' => 1),
291
            array('id' => 9),
292
        );
293
294
        $hydrator->expects($this->once())
295
            ->method('hydrateAll')
296
            ->will($this->returnValue($rows));
297
298
        $this->em->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\EntityManager>.

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...
299
          ->method('newHydrator') // was ->method('getHydrator')
300
          ->will($this->returnValue($hydrator));
301
302
        /* @var $query NativeQuery */
303
        $query = new NativeQuery($this->em);
304
305
        $this->em->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Doctrine\ORM\EntityManager>.

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...
306
            ->method('createNativeQuery')
307
            ->will($this->returnValue($query));
308
309
        $permissionDef = new PermissionDefinition(array('view'), 'Kunstmaan\NodeBundle\Entity\Node', 'n');
310
311
        /* @var $result array */
312
        $result = $this->object->getAllowedEntityIds($permissionDef);
313
314
        $this->assertEquals(array(1, 9), $result);
315
    }
316
317
    public function testGetAllowedEntityIdsNoEntity()
318
    {
319
        $this->expectException('InvalidArgumentException');
320
321
        $this->object->getAllowedEntityIds(new PermissionDefinition(array('view')));
322
    }
323
324
    public function testGetTokenStorage()
325
    {
326
        $this->assertSame($this->tokenStorage, $this->object->getTokenStorage());
327
    }
328
329
    private function getRoleMockData($anonymous = false)
330
    {
331
        if (Kernel::VERSION_ID >= 40300) {
332
            $rolesMethodName = 'getRoleNames';
333
            $reachableRolesMethodName = 'getReachableRoleNames';
334
            $roles = ['ROLE_KING'];
335
            $allRoles = [$roles[0], 'ROLE_SUBJECT'];
336
        } else {
337
            $rolesMethodName = 'getRoles';
338
            $reachableRolesMethodName = 'getReachableRoles';
339
            $roles = $anonymous ? [] : [new Role('ROLE_KING')];
340
            $allRoles = $anonymous ? [] : [$roles[0], new Role('ROLE_SUBJECT')];
341
        }
342
343
        return [
344
            $rolesMethodName,
345
            $roles,
346
            $reachableRolesMethodName,
347
            $allRoles,
348
        ];
349
    }
350
}
351