addMetadataCacheItem()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/*
4
 *
5
 * (c) Yaroslav Honcharuk <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Yarhon\RouteGuardBundle\Tests\Routing;
12
13
use PHPUnit\Framework\TestCase;
14
use Psr\Cache\CacheItemPoolInterface;
15
use Symfony\Component\Cache\Adapter\ArrayAdapter;
16
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
17
use Symfony\Component\Routing\RequestContext;
18
use Symfony\Component\HttpFoundation\ParameterBag;
19
use Yarhon\RouteGuardBundle\Routing\RequestAttributesFactory;
20
use Yarhon\RouteGuardBundle\Routing\RouteContext;
21
use Yarhon\RouteGuardBundle\Routing\RouteMetadata;
22
use Yarhon\RouteGuardBundle\Exception\RuntimeException;
23
24
/**
25
 * @author Yaroslav Honcharuk <[email protected]>
26
 */
27
class RequestAttributesFactoryTest extends TestCase
28
{
29
    private $metadataCache;
30
31
    private $urlGenerator;
32
33
    private $urlGeneratorContext;
34
35
    private $factory;
36
37
    public function setUp()
38
    {
39
        $this->metadataCache = new ArrayAdapter(0, false);
40
41
        $this->urlGenerator = $this->createMock(UrlGeneratorInterface::class);
42
43
        $this->urlGeneratorContext = $this->createMock(RequestContext::class);
44
45
        $this->urlGenerator->method('getContext')
0 ignored issues
show
Bug introduced by
The method method() does not exist on PHPUnit\Framework\MockObject\MockObject. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
        $this->urlGenerator->/** @scrutinizer ignore-call */ 
46
                             method('getContext')

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...
46
            ->willReturn($this->urlGeneratorContext);
47
48
        $this->factory = new RequestAttributesFactory($this->metadataCache, $this->urlGenerator);
49
    }
50
51
    /**
52
     * @dataProvider createAttributesDataProvider
53
     */
54
    public function testCreateAttributes($routeMetadata, $routeContext, $generatorContext, $expected)
55
    {
56
        $this->addMetadataCacheItem($routeContext->getName(), $routeMetadata);
57
58
        $this->urlGeneratorContext->method('getParameters')
59
            ->willReturn($generatorContext);
60
61
        $attributes = $this->factory->createAttributes($routeContext);
62
63
        $this->assertEquals($expected, $attributes);
64
    }
65
66
    public function createAttributesDataProvider()
67
    {
68
        return [
69
            [
70
                // test default values
71
                new RouteMetadata(['q' => 1], []),
72
                new RouteContext('index', []),
73
                [],
74
                new ParameterBag(['q' => 1]),
75
            ],
76
            [
77
                // test numerically indexed and null parameters are ignored
78
                new RouteMetadata(['page' => 1], []),
79
                new RouteContext('index', [0 => 'test', 'page' => null]),
80
                [],
81
                new ParameterBag(['page' => 1]),
82
            ],
83
            [
84
                // test context parameters and generate call parameters are ignored if not in route variable list
85
                new RouteMetadata([], ['page']),
86
                new RouteContext('index', ['z' => 4, 'page' => 1]),
87
                ['q' => 3],
88
                new ParameterBag(['page' => 1]),
89
            ],
90
            [
91
                // test context parameters replace defaults
92
                new RouteMetadata(['page' => 1], ['page']),
93
                new RouteContext('index', []),
94
                ['page' => 3],
95
                new ParameterBag(['page' => 3]),
96
            ],
97
            [
98
                // test parameters replace defaults
99
                new RouteMetadata(['page' => 1], ['page']),
100
                new RouteContext('index', ['page' => 3]),
101
                [],
102
                new ParameterBag(['page' => 3]),
103
            ],
104
            [
105
                // test parameters replace context parameters
106
                new RouteMetadata([], ['page']),
107
                new RouteContext('index', ['page' => 3]),
108
                ['page' => 1],
109
                new ParameterBag(['page' => 3]),
110
            ],
111
        ];
112
    }
113
114
    public function testCreateAttributesMissingParametersException()
115
    {
116
        $routeMetadata = new RouteMetadata([], ['page']);
117
        $routeContext = new RouteContext('index');
118
119
        $this->addMetadataCacheItem($routeContext->getName(), $routeMetadata);
120
121
        $this->urlGeneratorContext->method('getParameters')
122
            ->willReturn([]);
123
124
        $this->expectException(RuntimeException::class);
125
        $this->expectExceptionMessage('Some mandatory parameters are missing ("page") to get attributes for route.');
126
127
        $this->factory->createAttributes($routeContext);
128
    }
129
130
    public function testCreateAttributesNoMetadataException()
131
    {
132
        $routeContext = new RouteContext('index');
133
134
        $this->expectException(RuntimeException::class);
135
        $this->expectExceptionMessage('Cannot get RouteMetadata for route "index".');
136
137
        $this->factory->createAttributes($routeContext);
138
    }
139
140
    public function testCreateAttributesInternalCache()
141
    {
142
        $routeMetadata = new RouteMetadata([], ['page']);
143
144
        $routeContextOne = new RouteContext('index', ['page' => 5]);
145
        $routeContextTwo = $routeContextOne;
146
        $routeContextThree = new RouteContext('index2', ['page' => 5]);
147
        $routeContextFour = $routeContextThree;
148
149
        $this->addMetadataCacheItem('index', $routeMetadata);
150
        $this->addMetadataCacheItem('index2', $routeMetadata);
151
152
        $this->urlGeneratorContext->method('getParameters')
153
            ->willReturn([]);
154
155
        $attributesOne = $this->factory->createAttributes($routeContextOne);
156
        $attributesTwo = $this->factory->createAttributes($routeContextTwo);
157
        $attributesThree = $this->factory->createAttributes($routeContextThree);
158
        $attributesFour = $this->factory->createAttributes($routeContextFour);
159
160
        $this->assertSame($attributesOne, $attributesTwo);
161
        $this->assertSame($attributesThree, $attributesFour);
162
        $this->assertNotSame($attributesOne, $attributesThree);
163
    }
164
165
    /**
166
     * @dataProvider getAttributeNamesDataProvider
167
     */
168
    public function testGetAttributeNames($routeMetadata, $expected)
169
    {
170
        $names = $this->factory->getAttributeNames($routeMetadata);
171
172
        $this->assertEquals($expected, $names);
173
    }
174
175
    public function getAttributeNamesDataProvider()
176
    {
177
        return [
178
            [
179
                new RouteMetadata([], ['page']),
180
                ['page'],
181
            ],
182
            [
183
                new RouteMetadata(['language' => 'en'], []),
184
                ['language'],
185
            ],
186
            [
187
                new RouteMetadata(['language' => 'en'], ['page']),
188
                ['page', 'language'],
189
            ],
190
            [
191
                new RouteMetadata(['language' => 'en'], ['page', 'language']),
192
                ['page', 'language'],
193
            ],
194
        ];
195
    }
196
197
    private function addMetadataCacheItem($name, $value)
198
    {
199
        $cacheItem = $this->metadataCache->getItem($name);
200
        $cacheItem->set($value);
201
        $this->metadataCache->save($cacheItem);
202
    }
203
}
204