Completed
Push — master ( b305b3...f4a7a9 )
by John
02:47
created

SwaggerRouteLoaderTest::canUseDiKeyAsOperationId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 22
rs 9.2
cc 1
eloc 15
nc 1
nop 0
1
<?php
2
/*
3
 * This file is part of the KleijnWeb\SwaggerBundle package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace KleijnWeb\SwaggerBundle\Tests\Routing;
10
11
use KleijnWeb\SwaggerBundle\Routing\SwaggerRouteLoader;
12
use Symfony\Component\Routing\Route;
13
14
/**
15
 * @author John Kleijn <[email protected]>
16
 */
17
class SwaggerRouteLoaderTest extends \PHPUnit_Framework_TestCase
18
{
19
    const DOCUMENT_PATH = '/totally/non-existent/path';
20
21
    /**
22
     * @var \PHPUnit_Framework_MockObject_MockObject
23
     */
24
    private $repositoryMock;
25
26
    /**
27
     * @var \PHPUnit_Framework_MockObject_MockObject
28
     */
29
    private $documentMock;
30
31
    /**
32
     * @var SwaggerRouteLoader
33
     */
34
    private $loader;
35
36
    /**
37
     * Create mocks
38
     */
39
    protected function setUp()
40
    {
41
        $this->documentMock = $this
42
            ->getMockBuilder('KleijnWeb\SwaggerBundle\Document\SwaggerDocument')
43
            ->disableOriginalConstructor()
44
            ->getMock();
45
46
        $this->repositoryMock = $this
47
            ->getMockBuilder('KleijnWeb\SwaggerBundle\Document\DocumentRepository')
48
            ->disableOriginalConstructor()
49
            ->getMock();
50
51
        $this->repositoryMock
52
            ->expects($this->any())
53
            ->method('get')
54
            ->willReturn($this->documentMock);
55
56
        $this->loader = new SwaggerRouteLoader($this->repositoryMock);
57
    }
58
59
    /**
60
     * @test
61
     */
62
    public function supportSwaggerAsRouteTypeOnly()
63
    {
64
        $this->assertFalse($this->loader->supports('/a/b/c'));
65
        $this->assertTrue($this->loader->supports('/a/b/c', 'swagger'));
66
    }
67
68
    /**
69
     * @test
70
     */
71 View Code Duplication
    public function canLoadMultipleDocuments()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
72
    {
73
        $this->documentMock
74
            ->expects($this->any())
75
            ->method('getPathDefinitions')
76
            ->willReturn([]);
77
78
        $this->loader->load(self::DOCUMENT_PATH);
79
        $this->loader->load(self::DOCUMENT_PATH . '2');
80
    }
81
82
    /**
83
     * @test
84
     */
85
    public function loadingMultipleDocumentWillPreventRouteKeyCollisions()
86
    {
87
        $pathDefinitions = (object)[
88
            '/a'     => (object)['get' => (object)[]],
89
            '/a/b'   => (object)['get' => (object)[], 'post' => (object)[]],
90
            '/a/b/c' => (object)['put' => (object)[]],
91
        ];
92
93
        $this->documentMock
94
            ->expects($this->exactly(2))
95
            ->method('getPathDefinitions')
96
            ->willReturn($pathDefinitions);
97
98
        $routes1 = $this->loader->load(self::DOCUMENT_PATH);
99
        $routes2 = $this->loader->load(self::DOCUMENT_PATH . '2');
100
        $this->assertSame(count($routes1), count(array_diff_key($routes1->all(), $routes2->all())));
101
    }
102
103
    /**
104
     * @test
105
     * @expectedException \RuntimeException
106
     */
107 View Code Duplication
    public function cannotTryToLoadSameDocumentMoreThanOnce()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
108
    {
109
        $this->documentMock
110
            ->expects($this->any())
111
            ->method('getPathDefinitions')
112
            ->willReturn([]);
113
114
        $this->loader->load(self::DOCUMENT_PATH);
115
        $this->loader->load(self::DOCUMENT_PATH);
116
    }
117
118
    /**
119
     * @test
120
     */
121 View Code Duplication
    public function willReturnRouteCollection()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
122
    {
123
        $this->documentMock
124
            ->expects($this->once())
125
            ->method('getPathDefinitions')
126
            ->willReturn([]);
127
128
        $routes = $this->loader->load(self::DOCUMENT_PATH);
129
        $this->assertInstanceOf('Symfony\Component\Routing\RouteCollection', $routes);
130
    }
131
132
    /**
133
     * @test
134
     */
135
    public function routeCollectionWillContainOneRouteForEveryPathAndMethod()
136
    {
137
        $pathDefinitions = (object)[
138
            '/a' => (object)['get' => (object)[], 'post' => (object)[]],
139
            '/b' => (object)['get' => (object)[]],
140
        ];
141
142
        $this->documentMock
143
            ->expects($this->once())
144
            ->method('getPathDefinitions')
145
            ->willReturn($pathDefinitions);
146
147
        $routes = $this->loader->load(self::DOCUMENT_PATH);
148
149
        $this->assertCount(3, $routes);
150
    }
151
152
    /**
153
     * @test
154
     */
155 View Code Duplication
    public function routeCollectionWillIncludeSeparateRoutesForSubPaths()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
156
    {
157
        $pathDefinitions = (object)[
158
            '/a'     => (object)['get' => (object)[]],
159
            '/a/b'   => (object)['get' => (object)[]],
160
            '/a/b/c' => (object)['get' => (object)[]],
161
        ];
162
163
        $this->documentMock
164
            ->expects($this->once())
165
            ->method('getPathDefinitions')
166
            ->willReturn($pathDefinitions);
167
168
        $routes = $this->loader->load(self::DOCUMENT_PATH);
169
170
        $this->assertCount(3, $routes);
171
    }
172
173
    /**
174
     * @test
175
     */
176
    public function canUseDiKeyAsOperationId()
177
    {
178
        $expected = 'my.controller.key:methodName';
179
        $pathDefinitions = (object)[
180
            '/a' => [
181
                'get'  => (object)[],
182
                'post' => (object)['operationId' => $expected]
183
            ],
184
            '/b' => (object)['get' => (object)[]],
185
        ];
186
187
        $this->documentMock
188
            ->expects($this->any())
189
            ->method('getPathDefinitions')
190
            ->willReturn($pathDefinitions);
191
192
        $routes = $this->loader->load(self::DOCUMENT_PATH);
193
194
        $actual = $routes->get('swagger.path.a.my.controller.key:methodName');
195
        $this->assertNotNull($actual);
196
        $this->assertSame($expected, $actual->getDefault('_controller'));
197
    }
198
199
    /**
200
     * @test
201
     */
202 View Code Duplication
    public function routeCollectionWillIncludeSeparateRoutesForSubPathMethodCombinations()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
203
    {
204
        $pathDefinitions = (object)[
205
            '/a'     => (object)['get' => (object)[]],
206
            '/a/b'   => (object)['get' => (object)[], 'post' => (object)[]],
207
            '/a/b/c' => (object)['put' => (object)[]],
208
        ];
209
210
        $this->documentMock
211
            ->expects($this->once())
212
            ->method('getPathDefinitions')
213
            ->willReturn($pathDefinitions);
214
215
        $routes = $this->loader->load(self::DOCUMENT_PATH);
216
217
        $this->assertCount(4, $routes);
218
    }
219
220
    /**
221
     * @test
222
     */
223
    public function routeCollectionWillContainPathFromSwaggerDoc()
224
    {
225
        $pathDefinitions = (object)[
226
            '/a'                => (object)['get' => (object)[]],
227
            '/a/b'              => (object)['get' => (object)[]],
228
            '/a/b/c'            => (object)['get' => (object)[]],
229
            '/d/f/g'            => (object)['get' => (object)[]],
230
            '/1/2/3'            => (object)['get' => (object)[]],
231
            '/foo/{bar}/{blah}' => (object)['get' => (object)[]],
232
            '/z'                => (object)['get' => (object)[]],
233
        ];
234
235
        $this->documentMock
236
            ->expects($this->once())
237
            ->method('getPathDefinitions')
238
            ->willReturn($pathDefinitions);
239
240
        $routes = $this->loader->load(self::DOCUMENT_PATH);
241
242
        $definitionPaths = array_keys((array)$pathDefinitions);
243
        sort($definitionPaths);
244
        $routePaths = array_map(function ($route) {
245
            return $route->getPath();
246
        }, $routes->getIterator()->getArrayCopy());
247
        sort($routePaths);
248
        $this->assertSame($definitionPaths, $routePaths);
249
    }
250
251
    /**
252
     * @test
253
     */
254
    public function willAddRequirementsForIntegerPathParams()
255
    {
256
        $pathDefinitions = (object)[
257
            '/a' => (object)[
258
                'get' => (object)[
259
                    'parameters' => (object)[
260
                        (object)['name' => 'foo', 'in' => 'path', 'type' => 'integer']
261
                    ]
262
                ]
263
            ],
264
        ];
265
266
        $this->documentMock
267
            ->expects($this->once())
268
            ->method('getPathDefinitions')
269
            ->willReturn($pathDefinitions);
270
271
        $this->documentMock
272
            ->expects($this->once())
273
            ->method('getOperationDefinition')
274
            ->with('/a', 'get')
275
            ->willReturn($pathDefinitions->{'/a'}->get);
276
277
        $routes = $this->loader->load(self::DOCUMENT_PATH);
278
        $actual = $routes->get('swagger.path.a.get');
279
        $this->assertNotNull($actual);
280
        $requirements = $actual->getRequirements();
281
        $this->assertNotNull($requirements);
282
283
        $this->assertSame($requirements['foo'], '\d+');
284
    }
285
286
    /**
287
     * @test
288
     */
289
    public function willAddRequirementsForStringPatternParams()
290
    {
291
        $expected = '\d{2}hello';
292
        $pathDefinitions = (object)[
293
            '/a' => (object)[
294
                'get' => (object)[
295
                    'parameters' => (object)[
296
                        (object)['name' => 'aString', 'in' => 'path', 'type' => 'string', 'pattern' => $expected]
297
                    ]
298
                ]
299
            ],
300
        ];
301
302
        $this->documentMock
303
            ->expects($this->once())
304
            ->method('getPathDefinitions')
305
            ->willReturn($pathDefinitions);
306
307
        $this->documentMock
308
            ->expects($this->once())
309
            ->method('getOperationDefinition')
310
            ->with('/a', 'get')
311
            ->willReturn($pathDefinitions->{'/a'}->get);
312
313
        $routes = $this->loader->load(self::DOCUMENT_PATH);
314
        $actual = $routes->get('swagger.path.a.get');
315
        $this->assertNotNull($actual);
316
        $requirements = $actual->getRequirements();
317
        $this->assertNotNull($requirements);
318
319
        $this->assertSame($expected, $requirements['aString']);
320
    }
321
322
    /**
323
     * @test
324
     */
325
    public function willAddRequirementsForStringEnumParams()
326
    {
327
        $enum = ['a', 'b', 'c'];
328
        $expected = '(a|b|c)';
329
        $pathDefinitions = (object)[
330
            '/a' => (object)[
331
                'get' => (object)[
332
                    'parameters' => (object)[
333
                        (object)['name' => 'aString', 'in' => 'path', 'type' => 'string', 'enum' => $enum]
334
                    ]
335
                ]
336
            ],
337
        ];
338
339
        $this->documentMock
340
            ->expects($this->once())
341
            ->method('getPathDefinitions')
342
            ->willReturn($pathDefinitions);
343
344
        $this->documentMock
345
            ->expects($this->once())
346
            ->method('getOperationDefinition')
347
            ->with('/a', 'get')
348
            ->willReturn($pathDefinitions->{'/a'}->get);
349
350
        $routes = $this->loader->load(self::DOCUMENT_PATH);
351
        $actual = $routes->get('swagger.path.a.get');
352
        $this->assertNotNull($actual);
353
        $requirements = $actual->getRequirements();
354
        $this->assertNotNull($requirements);
355
356
        $this->assertSame($expected, $requirements['aString']);
357
    }
358
}
359