Completed
Push — develop ( eb5f8c...2537a4 )
by
unknown
13:09
created

PermissionsTest   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 607
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7
Metric Value
wmc 31
lcom 1
cbo 7
dl 0
loc 607
rs 9.8
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license    MIT
7
 * @copyright  2013 - 2015 Cross Solution <http://cross-solution.de>
8
 */
9
10
/** */
11
namespace CoreTest\Entity;
12
13
use Auth\Entity\User;
14
use Core\Entity\Permissions;
15
use Core\Entity\PermissionsInterface;
16
17
/**
18
 * Test the Permissions Entity
19
 *
20
 * @author Mathias Gelhausen <[email protected]>
21
 * @group  Core
22
 * @group  Core.Entity
23
 * @covers \Core\Entity\Permissions
24
 */
25
class PermissionsTest extends \PHPUnit_Framework_TestCase
26
{
27
28
    /*
29
     * General tests
30
     */
31
32
    /**
33
     * Tests if Permissions implements the correct interface
34
     *
35
     */
36
    public function testEntityImplementsInterface()
37
    {
38
        $target = new Permissions();
39
40
        $this->assertInstanceOf('\Core\Entity\PermissionsInterface', $target);
41
    }
42
43
    /**
44
     * Tests setting permissions type via constructor.
45
     *
46
     */
47
    public function testTypeIssetViaConstructor()
48
    {
49
        $target = new Permissions();
50
51
        $this->assertAttributeEquals(get_class($target), 'type', $target);
52
53
        $target = new Permissions('testTypeSet');
54
55
        $this->assertAttributeEquals('testTypeSet', 'type', $target);
56
    }
57
58
    /**
59
     * Tests if cloning a Permissions entity creates new instance of the collection of resources.
60
     *
61
     */
62
    public function testCloneCreatesNewResourceCollection()
63
    {
64
        $resource = $this->getMockBuilder('\Core\Entity\PermissionsResourceInterface')
65
                         ->getMockForAbstractClass();
66
67
        $target1 = new Permissions();
68
        $target1->grant($resource, Permissions::PERMISSION_ALL);
69
70
        $coll1 = $target1->getResources();
71
72
        $target2 = clone $target1;
73
        $coll2   = $target2->getResources();
74
75
        $this->assertNotSame($coll1, $coll2);
76
        $this->assertEquals($coll1, $coll2);
77
    }
78
79
    /*
80
     * __call Magic methods tests.
81
     */
82
83
    /**
84
     * Tests if Magic Methods throws expected exception when called without arguments.
85
     *
86
     * @expectedException \InvalidArgumentException
87
     * @expectedExceptionMessage Missing required parameter.
88
     */
89
    public function testMagicMethodsThrowsExceptionsIfCalledWithoutArguments()
90
    {
91
        $target = new Permissions();
92
93
        $target->grantAll();
94
    }
95
96
    /**
97
     * Tests if Magic Methods throws expected exception when unknown method is called.
98
     *
99
     * @expectedException \BadMethodCallException
100
     * @expectedExceptionMessage Unknown method
101
     */
102
    public function testMagicMethodsThrowsExceptionsIfCalledWithUnknownMethodName()
103
    {
104
        $target = new Permissions();
105
106
        $target->unknownMethod('dummyUser');
107
    }
108
109
    /**
110
     * Tests if Magic Methods calls correct concrete method.
111
     *
112
     */
113
    public function testMagicMethodsCallsProxiesToCorrectMethods()
114
    {
115
        $user         = 'dummyUser';
116
        $viewParams   = array($user, PermissionsInterface::PERMISSION_VIEW);
117
        $changeParams = array($user, PermissionsInterface::PERMISSION_CHANGE);
118
        $noneParams   = array($user, PermissionsInterface::PERMISSION_NONE);
119
        $allParams    = array($user, PermissionsInterface::PERMISSION_ALL);
120
121
        $target = $this->getMockBuilder('\Core\Entity\Permissions')->disableOriginalConstructor()
122
                       ->setMethods(array('isGranted', 'grant', 'revoke'))->getMock();
123
124
125
        $target->expects($this->exactly(4))
126
               ->method('isGranted')
127
               ->withConsecutive($viewParams, $changeParams, $noneParams, $allParams)
128
               ->willReturn(null);
129
130
        $target->expects($this->exactly(4))
131
               ->method('grant')
132
               ->withConsecutive($viewParams, $changeParams, $noneParams, $allParams)
133
               ->willReturn(null);
134
135
        $target->expects($this->exactly(4))
136
               ->method('revoke')
137
               ->withConsecutive($viewParams, $changeParams, $noneParams, $allParams)
138
               ->willReturn(null);
139
140
        /* Test starts here */
141
142
        foreach (array('View', 'Change', 'None', 'All') as $perm) {
143
            $isMethod     = "is{$perm}Granted";
144
            $grantMethod  = "grant{$perm}";
145
            $revokeMethod = "revoke{$perm}";
146
147
            $target->$isMethod($user);
148
            $target->$grantMethod($user);
149
            $target->$revokeMethod($user);
150
        }
151
    }
152
153
154
    /*
155
     * Test function grant()
156
     */
157
158
    /**
159
     * Tests if permissions are set correctly.
160
     *
161
     */
162
    public function testGrantPermissionsToUsers()
163
    {
164
        $resource = 'testUser';
165
        $target   = new Permissions();
166
167
        foreach (array(
168
                     PermissionsInterface::PERMISSION_VIEW   => array(true, false, false, false),
169
                     PermissionsInterface::PERMISSION_CHANGE => array(true, true, true, false),
170
                     PermissionsInterface::PERMISSION_ALL    => array(true, true, true, false),
171
                     PermissionsInterface::PERMISSION_NONE   => array(false, false, false, true),
172
                 ) as $perm => $expected
173
        ) {
174
175
            $target->grant($resource, $perm);
176
177
            $this->assertEquals($expected[0], $target->isGranted($resource, PermissionsInterface::PERMISSION_VIEW));
178
            $this->assertEquals($expected[1], $target->isGranted($resource, PermissionsInterface::PERMISSION_CHANGE));
179
            $this->assertEquals($expected[2], $target->isGranted($resource, PermissionsInterface::PERMISSION_ALL));
180
            $this->assertEquals($expected[3], $target->isGranted($resource, PermissionsInterface::PERMISSION_NONE));
181
182
        }
183
    }
184
185
    /**
186
     * Tests if the building of Permissions is defered when requested.
187
     *
188
     */
189
    public function testGrantDefersBuild()
190
    {
191
        $target = new Permissions();
192
193
        $target->grant('testUser', PermissionsInterface::PERMISSION_ALL, false);
194
195
        $this->assertFalse($target->isGranted('testUser', PermissionsInterface::PERMISSION_ALL));
196
        $target->build();
197
        $this->assertTrue($target->isGranted('testUser', PermissionsInterface::PERMISSION_ALL));
198
    }
199
200
    /**
201
     * Tests if the previously set permission is used when TRUE is passed as permission.
202
     *
203
     */
204
    public function testGrantUsesAssigendPermissionIfTrueIsPassed()
205
    {
206
        $target = new Permissions();
207
208
        $user = new User();
209
        $user->setId('testUser');
210
211
        $target->grant($user, PermissionsInterface::PERMISSION_VIEW);
212
        $target->grant($user, true);
213
214
        $this->assertTrue($target->isGranted($user, PermissionsInterface::PERMISSION_VIEW));
215
        $this->assertFalse($target->isGranted($user, PermissionsInterface::PERMISSION_CHANGE));
216
217
    }
218
219
    /**
220
     * Tests if grant traverses the resources when they are given as an array.
221
     *
222
     */
223
    public function testGrantTraversesIfResourceIsAnArray()
224
    {
225
        $user1 = new User();
226
        $user1->setId('user1');
227
        $user2 = new User();
228
        $user2->setId('user2');
229
230
        $resource = array($user1, $user2);
231
232
        $permission = PermissionsInterface::PERMISSION_ALL;
233
234
        $target = new Permissions();
235
236
        $target->grant($resource, $permission);
237
238
        $this->assertTrue($target->isGranted($user1, PermissionsInterface::PERMISSION_ALL));
239
        $this->assertTrue($target->isGranted($user2, PermissionsInterface::PERMISSION_ALL));
240
241
        $target = new Permissions();
242
243
        $target->grant($resource, PermissionsInterface::PERMISSION_VIEW, false);
244
245
        $this->assertFalse($target->isGranted($user1, PermissionsInterface::PERMISSION_VIEW),
246
                           'Disable build of permissions test failed!');
247
    }
248
249
    /**
250
     * Tests if the expected exception is thrown if an invalid permission is passed.
251
     *
252
     * @expectedException \InvalidArgumentException
253
     * @expectedExceptionMessage Invalid permission.
254
     */
255
    public function testGrantThrowsExceptionIfInvalidPermissionIsPassed()
256
    {
257
        $target = new Permissions();
258
259
        $this->setExpectedException('\InvalidArgumentException', 'Invalid permission.');
260
261
        $target->grant('test', 'invalidPermission');
262
    }
263
264
    /**
265
     * Tests using a resource object that implements PermissionsResourceInterface.
266
     *
267
     */
268
    public function testGrantWorksWhenPassingPermissionsResourceInterfaces()
269
    {
270
        $resource = $this->getMockBuilder('\Core\Entity\PermissionsResourceInterface')
271
                         ->getMockForAbstractClass();
272
273
        $resource->expects($this->any())
274
                 ->method('getPermissionsResourceId')->willReturn('resource');
275
276
        $userIds1 = array('user1', 'user2');
277
        $userIds2 = array('view' => array('user1', 'user2'), 'all' => array('user3', 'user4'));
278
        $resource->expects($this->exactly(4))
279
                 ->method('getPermissionsUserIds')
280
                 ->will($this->onConsecutiveCalls(
281
                             $userIds1, $userIds2, array(), null
282
                        ));
283
284
285
        $target = new Permissions();
286
287
        $target->grant($resource, Permissions::PERMISSION_NONE);
288
289
        $this->assertEquals(0, $target->getResources()->count());
290
291
        $target->grant($resource, Permissions::PERMISSION_VIEW);
292
293
        $coll = $target->getResources();
294
295
        $this->assertSame($resource, $coll->current());
296
        $this->assertEquals(array('resource' => array('view' => $userIds1)), $target->getAssigned());
297
298
        $target->grant($resource);
299
300
        $this->assertEquals(array('resource' => $userIds2), $target->getAssigned());
301
302
        $target->grant($resource, Permissions::PERMISSION_ALL);
303
304
        $this->assertEquals(array('resource' => array()), $target->getAssigned());
305
306
        $target->grant($resource, Permissions::PERMISSION_CHANGE);
307
308
        $this->assertEquals(array('resource' => array()), $target->getAssigned());
309
310
        $target->grant($resource, Permissions::PERMISSION_NONE);
311
312
        $this->assertEquals(0, $target->getResources()->count());
313
    }
314
315
    /*
316
     * Test function revoke()
317
     */
318
319
    /**
320
     * Data provider for testRevoke()
321
     *
322
     * @return array
323
     */
324
    public function revokeTestProvider()
325
    {
326
        return array(
327
            array(false, PermissionsInterface::PERMISSION_NONE, true),
328
            array(false, PermissionsInterface::PERMISSION_VIEW, true),
329
            array(true, PermissionsInterface::PERMISSION_CHANGE, false),
330
            array(true, PermissionsInterface::PERMISSION_ALL, true),
331
        );
332
    }
333
334
    /**
335
     * Tests revoking permissions.
336
     *
337
     * @dataProvider revokeTestProvider
338
     *
339
     * @param boolean $shouldBeAssigned Should the test assume, that the user was granted a permission prior to revoking it.
340
     * @param string  $perm             The permission to revoke
341
     * @param boolean $build            Passed as third paramter to revoke.
342
     */
343
    public function testRevoke($shouldBeAssigned, $perm, $build)
344
    {
345
        $resource = 'testUser';
346
347
        /* @var $target \Core\Entity\PermissionsInterface|\PHPUnit_Framework_MockObject_MockObject */
348
        $target = $this->getMockBuilder('\Core\Entity\Permissions')
349
                       ->disableOriginalConstructor()
350
                       ->setMethods(array('grant', 'isAssigned'))
351
                       ->getMock();
352
353
        if (PermissionsInterface::PERMISSION_NONE == $perm) {
354
            $target->expects($this->never())->method('isAssigned');
355
            $target->expects($this->never())->method('grant');
356
        } else if (!$shouldBeAssigned) {
357
            $target->expects($this->once())->method('isAssigned')->with($resource)->willReturn(false);
358
            $target->expects($this->never())->method('grant');
359
        } else {
360
            $target->expects($this->once())->method('isAssigned')->with($resource)->willReturn(true);
361
            $expPerm = PermissionsInterface::PERMISSION_CHANGE == $perm
362
                ? PermissionsInterface::PERMISSION_VIEW
363
                : PermissionsInterface::PERMISSION_NONE;
364
365
            $target->expects($this->once())->method('grant')->with($resource, $expPerm, $build)
366
                   ->will($this->returnSelf());
367
        }
368
369
        /* Test start here */
370
371
        $this->assertSame($target, $target->revoke($resource, $perm, $build));
372
373
    }
374
375
    /*
376
     * Test isGranted()
377
     */
378
379
    /**
380
     * Data provider for testIsGranted
381
     *
382
     * @return array
383
     */
384
    public function isGrantedTestProvider()
385
    {
386
        $user = new User();
387
        $user->setId('testUser');
388
389
        return array(
390
            array('testUser', false, array(true, false, false, false)),
391
            array('testUser', PermissionsInterface::PERMISSION_VIEW, array(false, true, false, false)),
392
            array('testUser', PermissionsInterface::PERMISSION_CHANGE, array(false, true, true, true)),
393
            array('testUser', PermissionsInterface::PERMISSION_ALL, array(false, true, true, true, true)),
394
            array($user, false, array(true, false, false, false)),
395
            array($user, PermissionsInterface::PERMISSION_VIEW, array(false, true, false, false)),
396
            array($user, PermissionsInterface::PERMISSION_CHANGE, array(false, true, true, true)),
397
            array($user, PermissionsInterface::PERMISSION_ALL, array(false, true, true, true, true)),
398
399
        );
400
    }
401
402
    /**
403
     * Tests if isGranted returns the expected results.
404
     *
405
     * @dataProvider isGrantedTestProvider
406
     *
407
     * @param string|User $user
408
     * @param string      $preGrant permission to grant the user prior to testing
409
     * @param boolean[]   $expected array with for elements which are the expected return values for
410
     *                              isGranted with the provided user who is granted the $preGrant permission for
411
     *                              all possible Permissions (ALL, NONE, VIEW, CHANGE).
412
     */
413
    public function testIsGranted($user, $preGrant, $expected)
414
    {
415
        $target = new Permissions();
416
417
        if (false !== $preGrant) {
418
            $target->grant($user, $preGrant);
419
        }
420
421
        foreach (array(
422
                     PermissionsInterface::PERMISSION_NONE,
423
                     PermissionsInterface::PERMISSION_VIEW,
424
                     PermissionsInterface::PERMISSION_CHANGE,
425
                     PermissionsInterface::PERMISSION_ALL
426
                 ) as $i => $perm
427
        ) {
428
            $this->assertEquals($expected[$i], $target->isGranted($user, $perm));
429
        }
430
    }
431
432
    /*
433
     * Test clear()
434
     */
435
436
    /**
437
     * tests clearing the Permissions entity.
438
     *
439
     */
440
    public function testClear()
441
    {
442
        $resource = $this->getMockBuilder('\Core\Entity\PermissionsResourceInterface')
443
                         ->getMockForAbstractClass();
444
445
        $resource->expects($this->any())
446
                 ->method('getPermissionsResourceId')->willReturn('resource');
447
448
        $resource->expects($this->exactly(1))->method('getPermissionsUserIds')
449
                 ->willReturn(array('test'));
450
451
        $target = new Permissions();
452
        $target->grant('test', Permissions::PERMISSION_ALL);
453
        $target->grant($resource, Permissions::PERMISSION_ALL);
454
455
        $expectAssigned = array(
456
            'user:test' => array('all' => array('test')),
457
            'resource'  => array('all' => array('test')),
458
        );
459
        $this->assertAttributeEquals(array('test'), 'view', $target);
460
        $this->assertAttributeEquals(array('test'), 'change', $target);
461
        $this->assertAttributeEquals($expectAssigned, 'assigned', $target);
462
        $this->assertAttributeInstanceOf('\Core\Entity\Collection\ArrayCollection', 'resources', $target);
463
464
        $target->clear();
465
466
        $this->assertAttributeEquals(array(), 'view', $target);
467
        $this->assertAttributeEquals(array(), 'change', $target);
468
        $this->assertAttributeEquals(array(), 'assigned', $target);
469
        $this->assertAttributeEquals(null, 'resources', $target);
470
    }
471
472
    /*
473
     * Test inherit()
474
     */
475
476
    /**
477
     * Tests if inheriting Permissions works as expected.
478
     *
479
     */
480
    public function testInherit()
481
    {
482
483
        $resource = $this->getMockBuilder('\Core\Entity\PermissionsResourceInterface')
484
                         ->getMockForAbstractClass();
485
486
        $resource->expects($this->any())
487
                 ->method('getPermissionsResourceId')->willReturn('resource');
488
489
        $resource->expects($this->any())->method('getPermissionsUserIds')
490
                 ->willReturn(array('test'));
491
492
        $target1 = new Permissions();
493
        $target2 = new Permissions();
494
495
        $target1->grant('userTarget1', Permissions::PERMISSION_ALL);
496
        $target1->grant($resource, Permissions::PERMISSION_VIEW);
497
        $target2->grant('user', Permissions::PERMISSION_VIEW);
498
499
        $target2->inherit($target1);
500
501
        $this->assertTrue($target2->isGranted('userTarget1', Permissions::PERMISSION_ALL));
502
        $this->assertTrue($target2->isGranted('test', Permissions::PERMISSION_VIEW));
503
504
505
    }
506
507
    /*
508
     * test isAssigned()
509
     */
510
511
    /**
512
     * Tests if isAssigned returns the expected results.
513
     *
514
     */
515
    public function testIsAssigned()
516
    {
517
        $target = new Permissions();
518
519
        $target->grant('tset', Permissions::PERMISSION_ALL);
520
521
        $this->assertFalse($target->isAssigned('test'));
522
        $this->assertTrue($target->isAssigned('tset'));
523
    }
524
525
    /*
526
     * test hasChanged()
527
     */
528
529
    /**
530
     * Tests if hasChanged returns correct values.
531
     *
532
     */
533
    public function testHasChangedReturnsTrueIfPermissionsChangedAndFalseIfNot()
534
    {
535
        $target = new Permissions();
536
537
        $this->assertFalse($target->hasChanged());
538
        $target->grant('testUser', PermissionsInterface::PERMISSION_ALL);
539
540
        $this->assertTrue($target->hasChanged(), 'Changed-Flag did not return true after change.');
541
    }
542
543
    /*
544
     * test Getter (getAssigned() and getResources() and getFrom()
545
     */
546
547
    /**
548
     * Tests if getAssigned returns the correct value.
549
     *
550
     */
551
    public function testGetAssignedReturnsSpecificationArray()
552
    {
553
        $target = new Permissions();
554
        $target->grantAll('testUser');
555
        $user = new User();
556
        $user->setId('testUser2');
557
        $target->grantView($user);
558
559
        $expected = array(
560
            'user:testUser'  => array(PermissionsInterface::PERMISSION_ALL => array('testUser')),
561
            'user:testUser2' => array(PermissionsInterface::PERMISSION_VIEW => array('testUser2')),
562
        );
563
564
        $this->assertEquals($expected, $target->getAssigned());
565
    }
566
567
    /**
568
     * Tests if getResource returns empty ArrayCollection when no resources are assigned.
569
     *
570
     */
571
    public function testGetResourcesReturnsEmptyArrayCollection()
572
    {
573
        $target = new Permissions();
574
575
        $coll = $target->getResources();
576
577
        $this->assertInstanceOf('\Core\Entity\Collection\ArrayCollection', $coll);
578
        $this->assertEquals(0, $coll->count());
579
    }
580
581
    /**
582
     * Tests if getResources returns an ArrayCollection with the correct resources contained in.
583
     *
584
     */
585
    public function testGetResourcesReturnsCollectionOfResources()
586
    {
587
        $resource = $this->getMockBuilder('\Core\Entity\PermissionsResourceInterface')
588
                         ->getMockForAbstractClass();
589
590
        $target = new Permissions();
591
        $target->grant($resource, PermissionsInterface::PERMISSION_ALL);
592
593
        $coll = $target->getResources();
594
595
        $this->assertEquals(1, $coll->count());
596
        $this->assertSame($resource, $coll->current());
597
    }
598
599
    /**
600
     * Tests if getFrom returns correct value.
601
     *
602
     */
603
    public function testGetFromReturnsCorrectPermission()
604
    {
605
        $grantedResource = $this->getMockBuilder('\Core\Entity\PermissionsResourceInterface')
606
                                ->getMockForAbstractClass();
607
608
        $grantedResource->expects($this->atLeastOnce())
609
                        ->method('getPermissionsUserIds')
610
                        ->will($this->onConsecutiveCalls(array(
611
                                                             'all'  => array('user1', 'user2'),
612
                                                             'view' => array('popel', 'dopel'),
613
                                                         ), array('all' => array('user3'))));
614
        $grantedResource->method('getPermissionsResourceId')->willReturn('grantResource');
615
616
        $ungrantedResource = $this->getMockBuilder('\Core\Entity\PermissionsResourceInterface')
617
                                  ->getMockForAbstractClass();
618
        $ungrantedResource->method('getPermissionsResourceId')->willReturn('ungrant');
619
620
        $target = new Permissions();
621
622
        $target->grant($grantedResource, PermissionsInterface::PERMISSION_ALL);
623
624
        $this->assertEquals(PermissionsInterface::PERMISSION_NONE, $target->getFrom($ungrantedResource));
625
        $this->assertEquals(null, $target->getFrom($grantedResource));
626
627
        $target->grant($grantedResource, PermissionsInterface::PERMISSION_CHANGE);
628
629
        $this->assertEquals(PermissionsInterface::PERMISSION_ALL, $target->getFrom($grantedResource));
630
    }
631
}