Completed
Push — master ( e9d211...82b216 )
by Craig
05:41
created

controllerProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\PermissionsModule\Tests\Api;
15
16
use Doctrine\Common\Annotations\AnnotationException;
17
use Doctrine\Common\Annotations\AnnotationReader;
18
use Symfony\Component\HttpFoundation\Request;
19
use Zikula\PermissionsModule\Annotation\PermissionCheck;
20
use Zikula\PermissionsModule\Api\PermissionApi;
21
use Zikula\PermissionsModule\Listener\ControllerPermissionCheckAnnotationReaderListener;
22
use Zikula\PermissionsModule\Tests\Api\Fixtures\BarController;
23
use Zikula\PermissionsModule\Tests\Api\Fixtures\FailController;
24
use Zikula\PermissionsModule\Tests\Api\Fixtures\FooController;
25
26
class CheckPermissionAnnotationTest extends AbstractPermissionTestCase
27
{
28
    /**
29
     * Call protected/private method of the listener class.
30
     *
31
     * @return mixed Method return
32
     * @throws \ReflectionException
33
     */
34
    private function invokeMethod(ControllerPermissionCheckAnnotationReaderListener $listener, string $methodName, array $parameters = [])
35
    {
36
        $reflection = new \ReflectionClass(get_class($listener));
37
        $method = $reflection->getMethod($methodName);
38
        $method->setAccessible(true);
39
40
        return $method->invokeArgs($listener, $parameters);
41
    }
42
43
    private function getListener()
44
    {
45
        $listener = new ControllerPermissionCheckAnnotationReaderListener(
46
            new PermissionApi($this->permRepo, $this->userRepo, $this->currentUserApi, $this->translator),
47
            new AnnotationReader()
48
        );
49
50
        return $listener;
51
    }
52
53
    public function testGetConstant()
54
    {
55
        $listener = $this->getListener();
56
        $this->assertEquals(ACCESS_ADMIN, $this->invokeMethod($listener, 'getConstant', ['admin']));
57
        $this->assertEquals(ACCESS_ADMIN, $this->invokeMethod($listener, 'getConstant', ['ACCESS_ADMIN']));
58
        $this->expectException(AnnotationException::class);
59
        $this->invokeMethod($listener, 'getConstant', ['foo']);
60
        $this->expectException(AnnotationException::class);
61
        $this->invokeMethod($listener, 'getConstant', [ACCESS_ADMIN]);
62
    }
63
64
    public function testHasFlag()
65
    {
66
        $listener = $this->getListener();
67
        $this->assertTrue($this->invokeMethod($listener, 'hasFlag', ['$foo']));
68
        $this->assertFalse($this->invokeMethod($listener, 'hasFlag', ['foo']));
69
    }
70
71
    /**
72
     * @dataProvider replaceableSchemaProvider
73
     */
74
    public function testReplaceRouteAttributes(string $expected, string $schema, array $attributes)
75
    {
76
        $listener = $this->getListener();
77
        $request = new Request([], [], $attributes);
78
        $this->assertEquals($expected, $this->invokeMethod($listener, 'replaceRouteAttributes', [$schema, $request]));
79
    }
80
81
    public function replaceableSchemaProvider(): array
82
    {
83
        return [
84
            ['5::', '$gid::', ['gid' => 5]],
85
            ['::5', '::$gid', ['gid' => 5]],
86
            [':5:', ':$gid:', ['gid' => 5]],
87
            ['gid$::', 'gid$::', ['gid' => 5]],
88
            ['gid$gid::', 'gid$gid::', ['gid' => 5]],
89
            [':gid$gid:5', ':gid$gid:$gid', ['gid' => 5]],
90
            ['AcmeFooModule::', '$_zkModule::', ['_zkModule' => 'AcmeFooModule']],
91
            ['AcmeFooModule:gid:5', '$_zkModule:gid:$gid', ['gid' => 5, '_zkModule' => 'AcmeFooModule']],
92
        ];
93
    }
94
95
    /**
96
     * @dataProvider schemaProvider
97
     */
98
    public function testIsValidSchema(bool $expected, array $schema)
99
    {
100
        $listener = $this->getListener();
101
        $this->assertEquals($expected, $this->invokeMethod($listener, 'isValidSchema', [$schema]));
102
    }
103
104
    public function schemaProvider(): array
105
    {
106
        return [
107
            [true, ['::', '::', 'admin']],
108
            [true, ['.*', '.*', 'ACCESS_OVERVIEW']],
109
            [true, ['::', ':(1|2|3):', 'admin']],
110
            [true, ['$foo::', '::$bar', 'edit']],
111
            [false, ['::', 'admin']],
112
            [false, ['::', '::', '::', 'admin']],
113
            [false, [1, '::', 'admin']],
114
            [false, [true, '::', 'admin']],
115
            [false, ['::', '::', ['foo']]],
116
        ];
117
    }
118
119
    /**
120
     * @dataProvider checkProvider
121
     */
122
    public function testFormatSchema(array $expected, array $data)
123
    {
124
        $listener = $this->getListener();
125
        $request = new Request([], [], ['gid' => 5, 'foo' => 'bar', '_zkModule' => 'AcmeFooModule']);
126
        $annot = new PermissionCheck($data);
127
        $this->assertEquals($expected, $this->invokeMethod($listener, 'formatSchema', [$annot, $request]));
128
    }
129
130
    public function checkProvider(): array
131
    {
132
        return [
133
            [['AcmeFooModule::', '::', ACCESS_ADMIN], ['value' => 'admin']],
134
            [['AcmeFooModule::', '::', ACCESS_ADMIN], ['value' => ['$_zkModule::', '::', 'admin']]],
135
            [['AcmeFooModule::', '::5', ACCESS_ADMIN], ['value' => ['$_zkModule::', '::$gid', 'admin']]],
136
            [['::', '::gid$gid', ACCESS_ADMIN], ['value' => ['::', '::gid$gid', 'admin']]],
137
            [['::', '5:5:5', ACCESS_ADMIN], ['value' => ['::', '$gid:$gid:$gid', 'admin']]],
138
            [['::', 'bar:$bar:5', ACCESS_ADMIN], ['value' => ['::', '$foo:$bar:$gid', 'admin']]],
139
            [['AcmeFooModule::bar', 'bar:bar:5', ACCESS_EDIT], ['value' => ['$_zkModule::$foo', '$foo:bar:$gid', 'ACCESS_EDIT']]],
140
        ];
141
    }
142
143
    /**
144
     * @dataProvider controllerProvider
145
     */
146
    public function testGetAnnotationValueFromController($expected, array $controller)
147
    {
148
        $listener = $this->getListener();
149
        if ($expected instanceof PermissionCheck) {
150
            $this->assertEquals($expected, $this->invokeMethod($listener, 'getAnnotationValueFromController', [$controller]));
151
        } else {
152
            $this->expectException($expected);
153
            $this->invokeMethod($listener, 'getAnnotationValueFromController', [$controller]);
154
        }
155
    }
156
157
    public function controllerProvider(): array
158
    {
159
        return [
160
            [new PermissionCheck(['value' => 'admin']), [new FooController(), 'firstAction']],
161
            [new PermissionCheck(['value' => ['AcmeFooModule::', '.*', 'overview']]), [new FooController(), 'secondAction']],
162
            [new PermissionCheck(['value' => ['$_zkModule', '::$gid', 'ACCESS_EDIT']]), [new FooController(), 'thirdAction']],
163
            [new PermissionCheck(['value' => 'admin']), [new FooController(), 'fourthAction']], // duplicates
164
            [new PermissionCheck(['value' => 'admin']), [new BarController(), 'firstAction']],
165
            [AnnotationException::class, [new FailController(), 'firstAction']],
166
        ];
167
    }
168
}
169