Completed
Push — ezp26445-rest_draft_http_cache ( 5bd2b6...c1f4a6 )
by
unknown
35:36
created

RepositoryTest::testCanUserComplex()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 104
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 77
nc 5
nop 3
dl 0
loc 104
rs 6.4589
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * File contains: eZ\Publish\Core\Repository\Tests\Service\Mock\RepositoryTest class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\Core\Repository\Tests\Service\Mock;
12
13
use eZ\Publish\API\Repository\Repository;
14
use eZ\Publish\Core\Repository\Values\User\UserReference;
15
use eZ\Publish\Core\Base\Exceptions\NotFound\LimitationNotFoundException;
16
use eZ\Publish\Core\Repository\Tests\Service\Mock\Base as BaseServiceMockTest;
17
use eZ\Publish\SPI\Persistence\User\RoleAssignment;
18
use eZ\Publish\SPI\Persistence\User\Role;
19
use eZ\Publish\SPI\Persistence\User\Policy;
20
21
/**
22
 * Mock test case for Repository.
23
 */
24
class RepositoryTest extends BaseServiceMockTest
25
{
26
    public function providerForTestHasAccessReturnsTrue()
27
    {
28
        return array(
29
            array(
30
                array(
31
                    25 => $this->createRole(
32
                        array(
33
                            array('dummy-module', 'dummy-function', 'dummy-limitation'),
34
                            array('dummy-module2', 'dummy-function2', 'dummy-limitation2'),
35
                        ),
36
                        25
37
                    ),
38
                    26 => $this->createRole(
39
                        array(
40
                            array('*', 'dummy-function', 'dummy-limitation'),
41
                        ),
42
                        26
43
                    ),
44
                ),
45
                array(
46
                    new RoleAssignment(
47
                        array(
48
                            'roleId' => 25,
49
                        )
50
                    ),
51
                    new RoleAssignment(
52
                        array(
53
                            'roleId' => 26,
54
                        )
55
                    ),
56
                ),
57
            ),
58
            array(
59
                array(
60
                    27 => $this->createRole(
61
                        array(
62
                            array('test-module', '*', 'dummy-limitation'),
63
                        ),
64
                        27
65
                    ),
66
                ),
67
                array(
68
                    new RoleAssignment(
69
                        array(
70
                            'roleId' => 27,
71
                        )
72
                    ),
73
                ),
74
            ),
75
            array(
76
                array(
77
                    28 => $this->createRole(
78
                        array(
79
                            array('test-module', 'test-function', '*'),
80
                        ),
81
                        28
82
                    ),
83
                ),
84
                array(
85
                    new RoleAssignment(
86
                        array(
87
                            'roleId' => 28,
88
                        )
89
                    ),
90
                ),
91
            ),
92
        );
93
    }
94
95
    /**
96
     * Test for the hasAccess() method.
97
     *
98
     * @covers \eZ\Publish\API\Repository\Repository::hasAccess
99
     * @dataProvider providerForTestHasAccessReturnsTrue
100
     */
101 View Code Duplication
    public function testHasAccessReturnsTrue(array $roles, array $roleAssignments)
102
    {
103
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
104
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
105
        $mockedRepository = $this->getRepository();
106
107
        $userHandlerMock
108
            ->expects($this->once())
109
            ->method('loadRoleAssignmentsByGroupId')
110
            ->with($this->isType('integer'), $this->equalTo(true))
111
            ->will($this->returnValue($roleAssignments));
112
113
        foreach ($roleAssignments as $at => $roleAssignment) {
114
            $userHandlerMock
115
                ->expects($this->at($at + 1))
116
                ->method('loadRole')
117
                ->with($roleAssignment->roleId)
118
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
119
        }
120
121
        $result = $mockedRepository->hasAccess('test-module', 'test-function');
122
123
        self::assertEquals(true, $result);
124
    }
125
126
    public function providerForTestHasAccessReturnsFalse()
127
    {
128
        return array(
129
            array(array(), array()),
130
            array(
131
                array(
132
                    29 => $this->createRole(
133
                        array(
134
                            array('dummy-module', 'dummy-function', 'dummy-limitation'),
135
                        ),
136
                        29
137
                    ),
138
                ),
139
                array(
140
                    new RoleAssignment(
141
                        array(
142
                            'roleId' => 29,
143
                        )
144
                    ),
145
                ),
146
            ),
147
            array(
148
                array(
149
                    30 => $this->createRole(
150
                        array(
151
                            array('test-module', 'dummy-function', 'dummy-limitation'),
152
                        ),
153
                        30
154
                    ),
155
                ),
156
                array(
157
                    new RoleAssignment(
158
                        array(
159
                            'roleId' => 30,
160
                        )
161
                    ),
162
                ),
163
            ),
164
        );
165
    }
166
167
    /**
168
     * Test for the hasAccess() method.
169
     *
170
     * @covers \eZ\Publish\API\Repository\Repository::hasAccess
171
     * @dataProvider providerForTestHasAccessReturnsFalse
172
     */
173 View Code Duplication
    public function testHasAccessReturnsFalse(array $roles, array $roleAssignments)
174
    {
175
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
176
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
177
        $mockedRepository = $this->getRepository();
178
179
        $userHandlerMock
180
            ->expects($this->once())
181
            ->method('loadRoleAssignmentsByGroupId')
182
            ->with($this->isType('integer'), $this->equalTo(true))
183
            ->will($this->returnValue($roleAssignments));
184
185
        foreach ($roleAssignments as $at => $roleAssignment) {
186
            $userHandlerMock
187
                ->expects($this->at($at + 1))
188
                ->method('loadRole')
189
                ->with($roleAssignment->roleId)
190
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
191
        }
192
193
        $result = $mockedRepository->hasAccess('test-module', 'test-function');
194
195
        self::assertEquals(false, $result);
196
    }
197
198
    /**
199
     * Test for the sudo() & hasAccess() method.
200
     *
201
     * @covers \eZ\Publish\Core\Repository\Repository::sudo
202
     * @covers \eZ\Publish\API\Repository\Repository::hasAccess
203
     * @dataProvider providerForTestHasAccessReturnsFalse
204
     */
205
    public function testHasAccessReturnsFalseButSudoSoTrue(array $roles, array $roleAssignments)
0 ignored issues
show
Unused Code introduced by
The parameter $roles is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $roleAssignments is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
206
    {
207
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
208
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
209
        $mockedRepository = $this->getRepository();
210
211
        $userHandlerMock
212
            ->expects($this->never())
213
            ->method($this->anything());
214
215
        $result = $mockedRepository->sudo(
216
            function (Repository $repo) {
217
                return $repo->hasAccess('test-module', 'test-function');
218
            }
219
        );
220
221
        self::assertEquals(true, $result);
222
    }
223
224
    /**
225
     * @return array
226
     */
227 View Code Duplication
    public function providerForTestHasAccessReturnsPermissionSets()
228
    {
229
        return array(
230
            array(
231
                array(
232
                    31 => $this->createRole(
233
                        array(
234
                            array('test-module', 'test-function', 'test-limitation'),
235
                        ),
236
                        31
237
                    ),
238
                ),
239
                array(
240
                    new RoleAssignment(
241
                        array(
242
                            'roleId' => 31,
243
                        )
244
                    ),
245
                ),
246
            ),
247
            array(
248
                array(
249
                    31 => $this->createRole(
250
                        array(
251
                            array('test-module', 'test-function', 'test-limitation'),
252
                        ),
253
                        31
254
                    ),
255
                    32 => $this->createRole(
256
                        array(
257
                            array('test-module', 'test-function', 'test-limitation2'),
258
                        ),
259
                        32
260
                    ),
261
                ),
262
                array(
263
                    new RoleAssignment(
264
                        array(
265
                            'roleId' => 31,
266
                        )
267
                    ),
268
                    new RoleAssignment(
269
                        array(
270
                            'roleId' => 32,
271
                        )
272
                    ),
273
                ),
274
            ),
275
        );
276
    }
277
278
    /**
279
     * Test for the hasAccess() method.
280
     *
281
     * @covers \eZ\Publish\API\Repository\Repository::hasAccess
282
     * @dataProvider providerForTestHasAccessReturnsPermissionSets
283
     */
284
    public function testHasAccessReturnsPermissionSets(array $roles, array $roleAssignments)
285
    {
286
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
287
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
288
        $roleDomainMapper = $this->getMock(
289
            'eZ\\Publish\\Core\\Repository\\Helper\\RoleDomainMapper',
290
            array('buildDomainPolicyObject'),
291
            array(),
292
            '',
293
            false
294
        );
295
        $repositoryMock = $this->getMock(
296
            'eZ\\Publish\\Core\\Repository\\Repository',
297
            array('getRoleDomainMapper', 'getCurrentUserReference'),
298
            array(
299
                $this->getPersistenceMock(),
300
                $this->getSPIMockHandler('Search\\Handler'),
301
            )
302
        );
303
304
        $repositoryMock
305
            ->expects($this->once())
306
            ->method('getRoleDomainMapper')
307
            ->will($this->returnValue($roleDomainMapper));
308
        $repositoryMock
309
            ->expects($this->once())
310
            ->method('getCurrentUserReference')
311
            ->will($this->returnValue(new UserReference(14)));
312
313
        $userHandlerMock
314
            ->expects($this->once())
315
            ->method('loadRoleAssignmentsByGroupId')
316
            ->with($this->isType('integer'), $this->equalTo(true))
317
            ->will($this->returnValue($roleAssignments));
318
319
        foreach ($roleAssignments as $at => $roleAssignment) {
320
            $userHandlerMock
321
                ->expects($this->at($at + 1))
322
                ->method('loadRole')
323
                ->with($roleAssignment->roleId)
324
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
325
        }
326
327
        $permissionSets = array();
328
        /* @var $roleAssignments \eZ\Publish\SPI\Persistence\User\RoleAssignment[] */
329
        $count = 0;
330
        foreach ($roleAssignments as $i => $roleAssignment) {
331
            $permissionSet = array('limitation' => null);
332 View Code Duplication
            foreach ($roles[$roleAssignment->roleId]->policies as $k => $policy) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
333
                $policyName = 'policy-' . $i . '-' . $k;
334
                if ($policy->limitations === 'notfound') {
335
                    $return = $this->throwException(new LimitationNotFoundException('notfound'));
336
                    $this->setExpectedException('eZ\Publish\Core\Base\Exceptions\NotFound\LimitationNotFoundException');
337
                } else {
338
                    $return = $this->returnValue($policyName);
339
                    $permissionSet['policies'][] = $policyName;
340
                }
341
342
                $roleDomainMapper
343
                    ->expects($this->at($count++))
344
                    ->method('buildDomainPolicyObject')
345
                    ->with($policy)
346
                    ->will($return);
347
            }
348
            if (!empty($permissionSet['policies'])) {
349
                $permissionSets[] = $permissionSet;
350
            }
351
        }
352
353
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
354
        self::assertEquals(
355
            $permissionSets,
356
            $repositoryMock->hasAccess('test-module', 'test-function')
357
        );
358
    }
359
360
    /**
361
     * @return array
362
     */
363 View Code Duplication
    public function providerForTestHasAccessReturnsException()
364
    {
365
        return array(
366
            array(
367
                array(
368
                    31 => $this->createRole(
369
                        array(
370
                            array('test-module', 'test-function', 'notfound'),
371
                        ),
372
                        31
373
                    ),
374
                ),
375
                array(
376
                    new RoleAssignment(
377
                        array(
378
                            'roleId' => 31,
379
                        )
380
                    ),
381
                ),
382
            ),
383
            array(
384
                array(
385
                    31 => $this->createRole(
386
                        array(
387
                            array('test-module', 'test-function', 'test-limitation'),
388
                        ),
389
                        31
390
                    ),
391
                    32 => $this->createRole(
392
                        array(
393
                            array('test-module', 'test-function', 'notfound'),
394
                        ),
395
                        32
396
                    ),
397
                ),
398
                array(
399
                    new RoleAssignment(
400
                        array(
401
                            'roleId' => 31,
402
                        )
403
                    ),
404
                    new RoleAssignment(
405
                        array(
406
                            'roleId' => 32,
407
                        )
408
                    ),
409
                ),
410
            ),
411
        );
412
    }
413
414
    /**
415
     * Test for the hasAccess() method.
416
     *
417
     * @covers \eZ\Publish\API\Repository\Repository::hasAccess
418
     * @dataProvider providerForTestHasAccessReturnsException
419
     * @expectedException \eZ\Publish\Core\Base\Exceptions\NotFound\LimitationNotFoundException
420
     */
421
    public function testHasAccessReturnsException(array $roles, array $roleAssignments)
422
    {
423
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
424
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
425
        $roleDomainMapper = $this->getMock(
426
            'eZ\\Publish\\Core\\Repository\\Helper\\RoleDomainMapper',
427
            array('buildDomainPolicyObject'),
428
            array(),
429
            '',
430
            false
431
        );
432
        $repositoryMock = $this->getMock(
433
            'eZ\\Publish\\Core\\Repository\\Repository',
434
            array('getRoleDomainMapper', 'getCurrentUserReference'),
435
            array(
436
                $this->getPersistenceMock(),
437
                $this->getSPIMockHandler('Search\\Handler'),
438
            )
439
        );
440
441
        $repositoryMock
442
            ->expects($this->once())
443
            ->method('getRoleDomainMapper')
444
            ->will($this->returnValue($roleDomainMapper));
445
        $repositoryMock
446
            ->expects($this->once())
447
            ->method('getCurrentUserReference')
448
            ->will($this->returnValue(new UserReference(14)));
449
450
        $userHandlerMock
451
            ->expects($this->once())
452
            ->method('loadRoleAssignmentsByGroupId')
453
            ->with($this->isType('integer'), $this->equalTo(true))
454
            ->will($this->returnValue($roleAssignments));
455
456
        foreach ($roleAssignments as $at => $roleAssignment) {
457
            $userHandlerMock
458
                ->expects($this->at($at + 1))
459
                ->method('loadRole')
460
                ->with($roleAssignment->roleId)
461
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
462
        }
463
464
        $permissionSets = array();
0 ignored issues
show
Unused Code introduced by
$permissionSets is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
465
        /* @var $roleAssignments \eZ\Publish\SPI\Persistence\User\RoleAssignment[] */
466
        $count = 0;
467
        foreach ($roleAssignments as $i => $roleAssignment) {
468
            $permissionSet = array('limitation' => null);
469 View Code Duplication
            foreach ($roles[$roleAssignment->roleId]->policies as $k => $policy) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
470
                $policyName = 'policy-' . $i . '-' . $k;
471
                if ($policy->limitations === 'notfound') {
472
                    $return = $this->throwException(new LimitationNotFoundException('notfound'));
473
                } else {
474
                    $return = $this->returnValue($policyName);
475
                    $permissionSet['policies'][] = $policyName;
476
                }
477
478
                $roleDomainMapper
479
                    ->expects($this->at($count++))
480
                    ->method('buildDomainPolicyObject')
481
                    ->with($policy)
482
                    ->will($return);
483
484
                if ($policy->limitations === 'notfound') {
485
                    break 2;// no more execution after exception
486
                }
487
            }
488
        }
489
490
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
491
        $repositoryMock->hasAccess('test-module', 'test-function');
492
    }
493
494 View Code Duplication
    public function providerForTestHasAccessReturnsPermissionSetsWithRoleLimitation()
495
    {
496
        return array(
497
            array(
498
                array(
499
                    32 => $this->createRole(
500
                        array(
501
                            array('test-module', 'test-function', 'test-limitation'),
502
                        ),
503
                        32
504
                    ),
505
                ),
506
                array(
507
                    new RoleAssignment(
508
                        array(
509
                            'roleId' => 32,
510
                            'limitationIdentifier' => 'test-role-limitation',
511
                            'values' => array('test-role-limitation-value'),
512
                        )
513
                    ),
514
                ),
515
            ),
516
            array(
517
                array(
518
                    33 => $this->createRole(array(array('*', '*', '*')), 33),
519
                ),
520
                array(
521
                    new RoleAssignment(
522
                        array(
523
                            'roleId' => 33,
524
                            'limitationIdentifier' => 'test-role-limitation',
525
                            'values' => array('test-role-limitation-value'),
526
                        )
527
                    ),
528
                ),
529
            ),
530
        );
531
    }
532
533
    /**
534
     * Test for the hasAccess() method.
535
     *
536
     * @covers \eZ\Publish\API\Repository\Repository::hasAccess
537
     * @dataProvider providerForTestHasAccessReturnsPermissionSetsWithRoleLimitation
538
     */
539
    public function testHasAccessReturnsPermissionSetsWithRoleLimitation(array $roles, array $roleAssignments)
540
    {
541
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
542
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
543
        $limitationTypeMock = $this->getMock('eZ\\Publish\\SPI\\Limitation\\Type');
544
        $repositoryMock = $this->getMock(
545
            'eZ\\Publish\\Core\\Repository\\Repository',
546
            array('getRoleDomainMapper', 'getCurrentUserReference', 'getLimitationService'),
547
            array(
548
                $this->getPersistenceMock(),
549
                $this->getSPIMockHandler('Search\\Handler'),
550
            )
551
        );
552
        $limitationService = $this->getMock(
553
            'eZ\\Publish\\Core\\Repository\\Helper\\LimitationService',
554
            array('getLimitationType')
555
        );
556
        $roleDomainMapper = $this->getMock(
557
            'eZ\\Publish\\Core\\Repository\\Helper\\RoleDomainMapper',
558
            array('buildDomainPolicyObject'),
559
            array(),
560
            '',
561
            false
562
        );
563
564
        $repositoryMock
565
            ->expects($this->once())
566
            ->method('getRoleDomainMapper')
567
            ->will($this->returnValue($roleDomainMapper));
568
        $repositoryMock
569
            ->expects($this->once())
570
            ->method('getLimitationService')
571
            ->will($this->returnValue($limitationService));
572
        $repositoryMock
573
            ->expects($this->once())
574
            ->method('getCurrentUserReference')
575
            ->will($this->returnValue(new UserReference(14)));
576
577
        $userHandlerMock
578
            ->expects($this->once())
579
            ->method('loadRoleAssignmentsByGroupId')
580
            ->with($this->isType('integer'), $this->equalTo(true))
581
            ->will($this->returnValue($roleAssignments));
582
583
        foreach ($roleAssignments as $at => $roleAssignment) {
584
            $userHandlerMock
585
                ->expects($this->at($at + 1))
586
                ->method('loadRole')
587
                ->with($roleAssignment->roleId)
588
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
589
        }
590
591
        $permissionSets = array();
592
        /** @var $roleAssignments \eZ\Publish\SPI\Persistence\User\RoleAssignment[] */
593
        foreach ($roleAssignments as $i => $roleAssignment) {
594
            $permissionSet = array();
595
            foreach ($roles[$roleAssignment->roleId]->policies as $k => $policy) {
596
                $policyName = "policy-{$i}-{$k}";
597
                $permissionSet['policies'][] = $policyName;
598
                $roleDomainMapper
599
                    ->expects($this->at($k))
600
                    ->method('buildDomainPolicyObject')
601
                    ->with($policy)
602
                    ->will($this->returnValue($policyName));
603
            }
604
605
            $permissionSet['limitation'] = "limitation-{$i}";
606
            $limitationTypeMock
607
                ->expects($this->at($i))
608
                ->method('buildValue')
609
                ->with($roleAssignment->values)
610
                ->will($this->returnValue($permissionSet['limitation']));
611
            $limitationService
612
                ->expects($this->any())
613
                ->method('getLimitationType')
614
                ->with($roleAssignment->limitationIdentifier)
615
                ->will($this->returnValue($limitationTypeMock));
616
617
            $permissionSets[] = $permissionSet;
618
        }
619
620
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
621
        self::assertEquals(
622
            $permissionSets,
623
            $repositoryMock->hasAccess('test-module', 'test-function')
624
        );
625
    }
626
627
    /**
628
     * Returns Role stub.
629
     *
630
     * @param array $policiesData
631
     * @param mixed $roleId
632
     *
633
     * @return \eZ\Publish\SPI\Persistence\User\Role
634
     */
635
    private function createRole(array $policiesData, $roleId = null)
636
    {
637
        $policies = array();
638
        foreach ($policiesData as $policyData) {
639
            $policies[] = new Policy(
640
                array(
641
                    'module' => $policyData[0],
642
                    'function' => $policyData[1],
643
                    'limitations' => $policyData[2],
644
                )
645
            );
646
        }
647
648
        return new Role(
649
            array(
650
                'id' => $roleId,
651
                'policies' => $policies,
652
            )
653
        );
654
    }
655
656
    public function providerForTestCanUserSimple()
657
    {
658
        return array(
659
            array(true, true),
660
            array(false, false),
661
            array(array(), false),
662
        );
663
    }
664
665
    /**
666
     * Test for the canUser() method.
667
     *
668
     * Tests execution paths with permission sets equaling to boolean value or empty array.
669
     *
670
     * @covers \eZ\Publish\API\Repository\Repository::canUser
671
     * @dataProvider providerForTestCanUserSimple
672
     */
673
    public function testCanUserSimple($permissionSets, $result)
674
    {
675
        $repositoryMock = $this->getMock(
676
            'eZ\\Publish\\Core\\Repository\\Repository',
677
            array('hasAccess', 'getCurrentUserReference'),
678
            array(
679
                $this->getPersistenceMock(),
680
                $this->getSPIMockHandler('Search\\Handler'),
681
            )
682
        );
683
684
        $repositoryMock
685
            ->expects($this->once())
686
            ->method('hasAccess')
687
            ->with($this->equalTo('test-module'), $this->equalTo('test-function'))
688
            ->will($this->returnValue($permissionSets));
689
690
        /** @var $valueObject \eZ\Publish\API\Repository\Values\ValueObject */
691
        $valueObject = $this->getMockForAbstractClass('eZ\\Publish\\API\\Repository\\Values\\ValueObject');
692
693
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
694
        self::assertEquals(
695
            $result,
696
            $repositoryMock->canUser('test-module', 'test-function', $valueObject, $valueObject)
697
        );
698
    }
699
700
    /**
701
     * Test for the canUser() method.
702
     *
703
     * Tests execution path with permission set defining no limitations.
704
     *
705
     * @covers \eZ\Publish\API\Repository\Repository::canUser
706
     */
707
    public function testCanUserWithoutLimitations()
708
    {
709
        $repositoryMock = $this->getMock(
710
            'eZ\\Publish\\Core\\Repository\\Repository',
711
            array('hasAccess', 'getCurrentUserReference'),
712
            array(
713
                $this->getPersistenceMock(),
714
                $this->getSPIMockHandler('Search\\Handler'),
715
            )
716
        );
717
718
        $policyMock = $this->getMock(
719
            'eZ\\Publish\\SPI\\Persistence\\User\\Policy',
720
            array('getLimitations'),
721
            array(),
722
            '',
723
            false
724
        );
725
        $policyMock
726
            ->expects($this->once())
727
            ->method('getLimitations')
728
            ->will($this->returnValue('*'));
729
        $permissionSets = array(
730
            array(
731
                'limitation' => null,
732
                'policies' => array($policyMock),
733
            ),
734
        );
735
        $repositoryMock
736
            ->expects($this->once())
737
            ->method('hasAccess')
738
            ->with($this->equalTo('test-module'), $this->equalTo('test-function'))
739
            ->will($this->returnValue($permissionSets));
740
741
        $repositoryMock
742
            ->expects($this->once())
743
            ->method('getCurrentUserReference')
744
            ->will($this->returnValue(new UserReference(14)));
745
746
        /** @var $valueObject \eZ\Publish\API\Repository\Values\ValueObject */
747
        $valueObject = $this->getMockForAbstractClass('eZ\\Publish\\API\\Repository\\Values\\ValueObject');
748
749
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
750
        self::assertTrue($repositoryMock->canUser('test-module', 'test-function', $valueObject, $valueObject));
751
    }
752
753
    /**
754
     * @return array
755
     */
756
    private function getPermissionSetsMock()
757
    {
758
        $roleLimitationMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\User\\Limitation');
759
        $roleLimitationMock
760
            ->expects($this->any())
761
            ->method('getIdentifier')
762
            ->will($this->returnValue('test-role-limitation-identifier'));
763
764
        $policyLimitationMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\User\\Limitation');
765
        $policyLimitationMock
766
            ->expects($this->any())
767
            ->method('getIdentifier')
768
            ->will($this->returnValue('test-policy-limitation-identifier'));
769
770
        $policyMock = $this->getMock(
771
            'eZ\\Publish\\SPI\\Persistence\\User\\Policy',
772
            array('getLimitations'),
773
            array(),
774
            '',
775
            false
776
        );
777
        $policyMock
778
            ->expects($this->any())
779
            ->method('getLimitations')
780
            ->will($this->returnValue(array($policyLimitationMock, $policyLimitationMock)));
781
782
        $permissionSet = array(
783
            'limitation' => clone $roleLimitationMock,
784
            'policies' => array($policyMock, $policyMock),
785
        );
786
        $permissionSets = array($permissionSet, $permissionSet);
787
788
        return $permissionSets;
789
    }
790
791
    /**
792
     * Provides evaluation results for two permission sets, each with a role limitation and two policies,
793
     * with two limitations per policy.
794
     *
795
     * @return array
796
     */
797
    public function providerForTestCanUserComplex()
798
    {
799
        return array(
800
            array(
801
                array(true, true),
802
                array(
803
                    array(
804
                        array(true, true),
805
                        array(true, true),
806
                    ),
807
                    array(
808
                        array(true, true),
809
                        array(true, true),
810
                    ),
811
                ),
812
                true,
813
            ),
814
            array(
815
                array(false, false),
816
                array(
817
                    array(
818
                        array(true, true),
819
                        array(true, true),
820
                    ),
821
                    array(
822
                        array(true, true),
823
                        array(true, true),
824
                    ),
825
                ),
826
                false,
827
            ),
828
            array(
829
                array(false, true),
830
                array(
831
                    array(
832
                        array(true, true),
833
                        array(true, true),
834
                    ),
835
                    array(
836
                        array(true, true),
837
                        array(true, true),
838
                    ),
839
                ),
840
                true,
841
            ),
842
            array(
843
                array(false, true),
844
                array(
845
                    array(
846
                        array(true, true),
847
                        array(true, true),
848
                    ),
849
                    array(
850
                        array(true, false),
851
                        array(true, true),
852
                    ),
853
                ),
854
                true,
855
            ),
856
            array(
857
                array(true, false),
858
                array(
859
                    array(
860
                        array(true, false),
861
                        array(false, true),
862
                    ),
863
                    array(
864
                        array(true, true),
865
                        array(true, true),
866
                    ),
867
                ),
868
                false,
869
            ),
870
        );
871
    }
872
873
    /**
874
     * Test for the canUser() method.
875
     *
876
     * Tests execution paths with permission sets containing limitations.
877
     *
878
     * @covers \eZ\Publish\API\Repository\Repository::canUser
879
     * @dataProvider providerForTestCanUserComplex
880
     */
881
    public function testCanUserComplex(array $roleLimitationEvaluations, array $policyLimitationEvaluations, $userCan)
882
    {
883
        /** @var $valueObject \eZ\Publish\API\Repository\Values\ValueObject */
884
        $valueObject = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\ValueObject');
885
        $repositoryMock = $this->getMock(
886
            'eZ\\Publish\\Core\\Repository\\Repository',
887
            array('getCurrentUserReference', 'hasAccess', 'getLimitationService'),
888
            array(),
889
            '',
890
            false
891
        );
892
        $roleServiceMock = $this->getMock(
0 ignored issues
show
Unused Code introduced by
$roleServiceMock is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
893
            'eZ\\Publish\\Core\\Repository\\RoleService',
894
            array(),
895
            array(
896
                $this->getRepositoryMock(),
897
                $this->getPersistenceMockHandler('User\\Handler'),
898
                $limitationService = $this->getMock(
899
                    'eZ\\Publish\\Core\\Repository\\Helper\\LimitationService',
900
                    array('getLimitationType')
901
                ),
902
                $this->getMock(
903
                    'eZ\\Publish\\Core\\Repository\\Helper\\RoleDomainMapper',
904
                    array(),
905
                    array($limitationService)
906
                ),
907
            ),
908
            '',
909
            false
910
        );
911
912
        $repositoryMock
913
            ->expects($this->once())
914
            ->method('getLimitationService')
915
            ->will($this->returnValue($limitationService));
916
917
        $permissionSets = $this->getPermissionSetsMock();
918
        $repositoryMock
919
            ->expects($this->once())
920
            ->method('hasAccess')
921
            ->with($this->equalTo('test-module'), $this->equalTo('test-function'))
922
            ->will($this->returnValue($permissionSets));
923
924
        $userRef = new UserReference(14);
925
        $repositoryMock
926
            ->expects($this->once())
927
            ->method('getCurrentUserReference')
928
            ->will($this->returnValue(new UserReference(14)));
929
930
        $invocation = 0;
931
        for ($i = 0; $i < count($permissionSets); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
932
            $limitation = $this->getMock('eZ\\Publish\\SPI\\Limitation\\Type');
933
            $limitation
934
                ->expects($this->once())
935
                ->method('evaluate')
936
                ->with($permissionSets[$i]['limitation'], $userRef, $valueObject, array($valueObject))
937
                ->will($this->returnValue($roleLimitationEvaluations[$i]));
938
            $limitationService
939
                ->expects($this->at($invocation++))
940
                ->method('getLimitationType')
941
                ->with('test-role-limitation-identifier')
942
                ->will($this->returnValue($limitation));
943
944
            if (!$roleLimitationEvaluations[$i]) {
945
                continue;
946
            }
947
948
            for ($j = 0; $j < count($permissionSets[$i]['policies']); ++$j) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
949
                /** @var $policy \eZ\Publish\API\Repository\Values\User\Policy */
950
                $policy = $permissionSets[$i]['policies'][$j];
951
                $limitations = $policy->getLimitations();
952
                for ($k = 0; $k < count($limitations); ++$k) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
953
                    $limitationsPass = true;
954
                    $limitation = $this->getMock('eZ\\Publish\\SPI\\Limitation\\Type');
955
                    $limitation
956
                        ->expects($this->once())
957
                        ->method('evaluate')
958
                        ->with($limitations[$k], $userRef, $valueObject, array($valueObject))
959
                        ->will($this->returnValue($policyLimitationEvaluations[$i][$j][$k]));
960
                    $limitationService
961
                        ->expects($this->at($invocation++))
962
                        ->method('getLimitationType')
963
                        ->with('test-policy-limitation-identifier')
964
                        ->will($this->returnValue($limitation));
965
966
                    if (!$policyLimitationEvaluations[$i][$j][$k]) {
967
                        $limitationsPass = false;
968
                        break;
969
                    }
970
                }
971
972
                /** @var $limitationsPass */
973
                if ($limitationsPass) {
0 ignored issues
show
Bug introduced by
The variable $limitationsPass does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
974
                    break 2;
975
                }
976
            }
977
        }
978
979
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
980
        self::assertEquals(
981
            $userCan,
982
            $repositoryMock->canUser('test-module', 'test-function', $valueObject, $valueObject)
983
        );
984
    }
985
986
    /**
987
     * Test for the canUser() method.
988
     *
989
     * @covers \eZ\Publish\API\Repository\Repository::canUser
990
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
991
     */
992
    public function testCanUserThrowsInvalidArgumentException()
993
    {
994
        $repositoryMock = $this->getMock(
995
            'eZ\\Publish\\Core\\Repository\\Repository',
996
            array('hasAccess'),
997
            array(),
998
            '',
999
            false
1000
        );
1001
1002
        $repositoryMock
1003
            ->expects($this->once())
1004
            ->method('hasAccess')
1005
            ->with($this->equalTo('test-module'), $this->equalTo('test-function'))
1006
            ->will($this->returnValue(array()));
1007
1008
        /** @var $valueObject \eZ\Publish\API\Repository\Values\ValueObject */
1009
        $valueObject = $this->getMockForAbstractClass('eZ\\Publish\\API\\Repository\\Values\\ValueObject');
1010
1011
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
1012
        $repositoryMock->canUser('test-module', 'test-function', $valueObject, 'This is not a target');
1013
    }
1014
1015
    /**
1016
     * Test for the setCurrentUser() and getCurrentUser() methods.
1017
     *
1018
     * @covers \eZ\Publish\API\Repository\Repository::setCurrentUser
1019
     * @covers \eZ\Publish\API\Repository\Repository::getCurrentUser
1020
     */
1021
    public function testSetAndGetCurrentUser()
1022
    {
1023
        $mockedRepository = $this->getRepository();
1024
        $user = $this->getStubbedUser(42);
1025
1026
        $mockedRepository->setCurrentUser($user);
1027
1028
        self::assertSame(
1029
            $user,
1030
            $mockedRepository->getCurrentUser()
1031
        );
1032
    }
1033
1034
    /**
1035
     * Test for the getCurrentUser() method.
1036
     *
1037
     * @covers \eZ\Publish\API\Repository\Repository::getCurrentUser
1038
     */
1039
    public function testGetCurrentUserReturnsAnonymousUser()
1040
    {
1041
        $userServiceMock = $this->getMock('eZ\\Publish\\API\\Repository\\UserService');
1042
        $repositoryMock = $this->getMock(
1043
            'eZ\\Publish\\Core\\Repository\\Repository',
1044
            array('getUserService'),
1045
            array(
1046
                $this->getPersistenceMock(),
1047
                $this->getSPIMockHandler('Search\\Handler'),
1048
                array(
1049
                    'user' => array(
1050
                        'anonymousUserID' => 10,
1051
                    ),
1052
                ),
1053
            )
1054
        );
1055
1056
        $userServiceMock
1057
            ->expects($this->once())
1058
            ->method('loadUser')
1059
            ->with(10)
1060
            ->will($this->returnValue('Anonymous User'));
1061
1062
        $repositoryMock
1063
            ->expects($this->once())
1064
            ->method('getUserService')
1065
            ->will($this->returnValue($userServiceMock));
1066
1067
        /* @var $repositoryMock \eZ\Publish\API\Repository\Repository */
1068
        self::assertEquals(
1069
            'Anonymous User',
1070
            $repositoryMock->getCurrentUser()
1071
        );
1072
    }
1073
1074
    /**
1075
     * Test for the beginTransaction() method.
1076
     *
1077
     * @covers \eZ\Publish\API\Repository\Repository::beginTransaction
1078
     */
1079
    public function testBeginTransaction()
1080
    {
1081
        $mockedRepository = $this->getRepository();
1082
        $persistenceHandlerMock = $this->getPersistenceMock();
1083
1084
        $persistenceHandlerMock->expects(
1085
            $this->once()
1086
        )->method(
1087
            'beginTransaction'
1088
        );
1089
1090
        $mockedRepository->beginTransaction();
1091
    }
1092
1093
    /**
1094
     * Test for the commit() method.
1095
     *
1096
     * @covers \eZ\Publish\API\Repository\Repository::commit
1097
     */
1098 View Code Duplication
    public function testCommit()
1099
    {
1100
        $mockedRepository = $this->getRepository();
1101
        $persistenceHandlerMock = $this->getPersistenceMock();
1102
1103
        $persistenceHandlerMock->expects(
1104
            $this->once()
1105
        )->method(
1106
            'commit'
1107
        );
1108
1109
        $mockedRepository->commit();
1110
    }
1111
1112
    /**
1113
     * Test for the commit() method.
1114
     *
1115
     * @covers \eZ\Publish\API\Repository\Repository::commit
1116
     * @expectedException \RuntimeException
1117
     */
1118 View Code Duplication
    public function testCommitThrowsRuntimeException()
1119
    {
1120
        $mockedRepository = $this->getRepository();
1121
        $persistenceHandlerMock = $this->getPersistenceMock();
1122
1123
        $persistenceHandlerMock->expects(
1124
            $this->once()
1125
        )->method(
1126
            'commit'
1127
        )->will(
1128
            $this->throwException(new \Exception())
1129
        );
1130
1131
        $mockedRepository->commit();
1132
    }
1133
1134
    /**
1135
     * Test for the rollback() method.
1136
     *
1137
     * @covers \eZ\Publish\API\Repository\Repository::rollback
1138
     */
1139 View Code Duplication
    public function testRollback()
1140
    {
1141
        $mockedRepository = $this->getRepository();
1142
        $persistenceHandlerMock = $this->getPersistenceMock();
1143
1144
        $persistenceHandlerMock->expects(
1145
            $this->once()
1146
        )->method(
1147
            'rollback'
1148
        );
1149
1150
        $mockedRepository->rollback();
1151
    }
1152
1153
    /**
1154
     * Test for the rollback() method.
1155
     *
1156
     * @covers \eZ\Publish\API\Repository\Repository::rollback
1157
     * @expectedException \RuntimeException
1158
     */
1159 View Code Duplication
    public function testRollbackThrowsRuntimeException()
1160
    {
1161
        $mockedRepository = $this->getRepository();
1162
        $persistenceHandlerMock = $this->getPersistenceMock();
1163
1164
        $persistenceHandlerMock->expects(
1165
            $this->once()
1166
        )->method(
1167
            'rollback'
1168
        )->will(
1169
            $this->throwException(new \Exception())
1170
        );
1171
1172
        $mockedRepository->rollback();
1173
    }
1174
}
1175