• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 14975216971

12 May 2025 02:41PM UTC coverage: 6.943% (-0.3%) from 7.243%
14975216971

push

github

web-flow
feat(openapi): license identifier (#7141)

3 of 5 new or added lines in 5 files covered. (60.0%)

23 existing lines in 1 file now uncovered.

11128 of 160284 relevant lines covered (6.94%)

6.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\Tests\Symfony\Bundle\DependencyInjection;
15

16
use ApiPlatform\Metadata\Exception\InvalidArgumentException;
17
use ApiPlatform\Symfony\Bundle\DependencyInjection\Configuration;
18
use Doctrine\ORM\OptimisticLockException;
19
use PHPUnit\Framework\TestCase;
20
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
21
use Symfony\Component\Config\Definition\ConfigurationInterface;
22
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
23
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
24
use Symfony\Component\Config\Definition\Processor;
25
use Symfony\Component\HttpFoundation\Response;
26
use Symfony\Component\Serializer\Exception\ExceptionInterface;
27

28
/**
29
 * @author Kévin Dunglas <dunglas@gmail.com>
30
 * @author Baptiste Meyer <baptiste.meyer@gmail.com>
31
 */
32
class ConfigurationTest extends TestCase
33
{
34
    private Configuration $configuration;
35

36
    private Processor $processor;
37

38
    protected function setUp(): void
39
    {
40
        $this->configuration = new Configuration();
×
41
        $this->processor = new Processor();
×
42
    }
43

44
    public function testDefaultConfig(): void
45
    {
46
        $this->runDefaultConfigTests();
×
47
    }
48

49
    public function testDefaultConfigWithMongoDbOdm(): void
50
    {
51
        $this->runDefaultConfigTests(['orm', 'odm']);
×
52
    }
53

54
    private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm']): void
55
    {
56
        $treeBuilder = $this->configuration->getConfigTreeBuilder();
×
57
        $config = $this->processor->processConfiguration($this->configuration, [
×
58
            'api_platform' => [
×
59
                'title' => 'title',
×
60
                'description' => 'description',
×
61
                'version' => '1.0.0',
×
62
                'doctrine' => [
×
63
                    'enabled' => \in_array('orm', $doctrineIntegrationsToLoad, true),
×
64
                ],
×
65
                'doctrine_mongodb_odm' => [
×
66
                    'enabled' => \in_array('odm', $doctrineIntegrationsToLoad, true),
×
67
                ],
×
68
            ],
×
69
        ]);
×
70

71
        $this->assertInstanceOf(ConfigurationInterface::class, $this->configuration);
×
72
        $this->assertInstanceOf(TreeBuilder::class, $treeBuilder);
×
73
        $this->assertEquals([
×
74
            'title' => 'title',
×
75
            'description' => 'description',
×
76
            'version' => '1.0.0',
×
77
            'show_webby' => true,
×
78
            'formats' => [
×
79
                'jsonld' => ['mime_types' => ['application/ld+json']],
×
80
            ],
×
81
            'docs_formats' => [
×
82
                'jsonopenapi' => ['mime_types' => ['application/vnd.openapi+json']],
×
83
                'yamlopenapi' => ['mime_types' => ['application/vnd.openapi+yaml']],
×
84
                'jsonld' => ['mime_types' => ['application/ld+json']],
×
85
                'html' => ['mime_types' => ['text/html']],
×
86
            ],
×
87
            'patch_formats' => [
×
88
                'json' => ['mime_types' => ['application/merge-patch+json']],
×
89
            ],
×
90
            'error_formats' => [
×
91
                'jsonproblem' => ['mime_types' => ['application/problem+json']],
×
92
                'jsonld' => ['mime_types' => ['application/ld+json']],
×
93
                'json' => ['mime_types' => ['application/problem+json', 'application/json']],
×
94
            ],
×
95
            'jsonschema_formats' => [],
×
96
            'exception_to_status' => [
×
97
                ExceptionInterface::class => Response::HTTP_BAD_REQUEST,
×
98
                InvalidArgumentException::class => Response::HTTP_BAD_REQUEST,
×
99
                OptimisticLockException::class => Response::HTTP_CONFLICT,
×
100
            ],
×
101
            'path_segment_name_generator' => 'api_platform.metadata.path_segment_name_generator.underscore',
×
102
            'inflector' => 'api_platform.metadata.inflector',
×
103
            'validator' => [
×
104
                'serialize_payload_fields' => [],
×
105
                'query_parameter_validation' => true,
×
106
            ],
×
107
            'name_converter' => null,
×
108
            'enable_swagger' => true,
×
109
            'enable_swagger_ui' => true,
×
110
            'enable_entrypoint' => true,
×
111
            'enable_re_doc' => true,
×
112
            'enable_docs' => true,
×
113
            'enable_profiler' => true,
×
114
            'graphql' => [
×
115
                'enabled' => true,
×
116
                'default_ide' => 'graphiql',
×
117
                'graphql_playground' => [
×
118
                    'enabled' => true,
×
119
                ],
×
120
                'graphiql' => [
×
121
                    'enabled' => true,
×
122
                ],
×
123
                'introspection' => [
×
124
                    'enabled' => true,
×
125
                ],
×
126
                'max_query_depth' => 20,
×
127
                'max_query_complexity' => 500,
×
128
                'nesting_separator' => '_',
×
129
                'collection' => [
×
130
                    'pagination' => [
×
131
                        'enabled' => true,
×
132
                    ],
×
133
                ],
×
134
            ],
×
135
            'elasticsearch' => [
×
136
                'enabled' => false,
×
137
                'hosts' => [],
×
138
            ],
×
139
            'oauth' => [
×
140
                'enabled' => false,
×
141
                'clientId' => '',
×
142
                'clientSecret' => '',
×
143
                'type' => 'oauth2',
×
144
                'flow' => 'application',
×
145
                'tokenUrl' => '',
×
146
                'authorizationUrl' => '',
×
147
                'refreshUrl' => '',
×
148
                'scopes' => [],
×
149
                'pkce' => false,
×
150
            ],
×
151
            'swagger' => [
×
152
                'versions' => [3],
×
153
                'api_keys' => [],
×
154
                'http_auth' => [],
×
155
                'swagger_ui_extra_configuration' => [],
×
156
                'persist_authorization' => false,
×
157
            ],
×
158
            'eager_loading' => [
×
159
                'enabled' => true,
×
160
                'max_joins' => 30,
×
161
                'force_eager' => true,
×
162
                'fetch_partial' => false,
×
163
            ],
×
164
            'collection' => [
×
165
                'exists_parameter_name' => 'exists',
×
166
                'order' => 'ASC',
×
167
                'order_parameter_name' => 'order',
×
168
                'order_nulls_comparison' => null,
×
169
                'pagination' => [
×
170
                    'enabled' => true,
×
171
                    'page_parameter_name' => 'page',
×
172
                    'enabled_parameter_name' => 'pagination',
×
173
                    'items_per_page_parameter_name' => 'itemsPerPage',
×
174
                    'partial_parameter_name' => 'partial',
×
175
                ],
×
176
            ],
×
177
            'mapping' => [
×
178
                'paths' => [],
×
179
            ],
×
180
            'http_cache' => [
×
181
                'invalidation' => [
×
182
                    'enabled' => false,
×
183
                    'varnish_urls' => [],
×
184
                    'request_options' => [],
×
185
                    'max_header_length' => 7500,
×
186
                    'purger' => 'api_platform.http_cache.purger.varnish',
×
187
                    'xkey' => ['glue' => ' '],
×
188
                    'urls' => [],
×
189
                    'scoped_clients' => [],
×
190
                ],
×
191
                'public' => null,
×
192
            ],
×
193
            'doctrine' => [
×
194
                'enabled' => \in_array('orm', $doctrineIntegrationsToLoad, true),
×
195
            ],
×
196
            'doctrine_mongodb_odm' => [
×
197
                'enabled' => \in_array('odm', $doctrineIntegrationsToLoad, true),
×
198
            ],
×
199
            'messenger' => [
×
200
                'enabled' => true,
×
201
            ],
×
202
            'mercure' => [
×
203
                'enabled' => true,
×
204
                'hub_url' => null,
×
205
                'include_type' => false,
×
206
            ],
×
207
            'resource_class_directories' => [],
×
208
            'asset_package' => null,
×
209
            'openapi' => [
×
210
                'contact' => [
×
211
                    'name' => null,
×
212
                    'url' => null,
×
213
                    'email' => null,
×
214
                ],
×
215
                'termsOfService' => null,
×
216
                'license' => [
×
217
                    'name' => null,
×
218
                    'url' => null,
×
NEW
219
                    'identifier' => null,
×
220
                ],
×
221
                'swagger_ui_extra_configuration' => [],
×
222
                'overrideResponses' => true,
×
223
                'tags' => [],
×
224
            ],
×
225
            'maker' => [
×
226
                'enabled' => true,
×
227
            ],
×
228
            'use_symfony_listeners' => false,
×
229
            'handle_symfony_errors' => false,
×
230
            'enable_link_security' => false,
×
231
            'serializer' => [
×
232
                'hydra_prefix' => null,
×
233
            ],
×
234
        ], $config);
×
235
    }
236

237
    public static function invalidHttpStatusCodeProvider(): array
238
    {
239
        return [
×
240
            [0],
×
241
            [99],
×
242
            [700],
×
243
            [1000],
×
244
        ];
×
245
    }
246

247
    #[\PHPUnit\Framework\Attributes\DataProvider('invalidHttpStatusCodeProvider')]
248
    public function testExceptionToStatusConfigWithInvalidHttpStatusCode($invalidHttpStatusCode): void
249
    {
250
        $this->expectException(InvalidConfigurationException::class);
×
251
        $this->expectExceptionMessageMatches('/The HTTP status code ".+" is not valid\\./');
×
252

253
        $this->processor->processConfiguration($this->configuration, [
×
254
            'api_platform' => [
×
255
                'exception_to_status' => [
×
256
                    \Exception::class => $invalidHttpStatusCode,
×
257
                ],
×
258
            ],
×
259
        ]);
×
260
    }
261

262
    public static function invalidHttpStatusCodeValueProvider(): array
263
    {
264
        return [
×
265
            [true],
×
266
            [null],
×
267
            [-\INF],
×
268
            [40.4],
×
269
            ['foo'],
×
270
            ['HTTP_FOO_BAR'],
×
271
        ];
×
272
    }
273

274
    #[\PHPUnit\Framework\Attributes\DataProvider('invalidHttpStatusCodeValueProvider')]
275
    public function testExceptionToStatusConfigWithInvalidHttpStatusCodeValue($invalidHttpStatusCodeValue): void
276
    {
277
        $this->expectException(InvalidTypeException::class);
×
278
        $this->expectExceptionMessageMatches('/Invalid type for path "api_platform\\.exception_to_status\\.Exception". Expected "?int"?, but got .+\\./');
×
279

280
        $this->processor->processConfiguration($this->configuration, [
×
281
            'api_platform' => [
×
282
                'exception_to_status' => [
×
283
                    \Exception::class => $invalidHttpStatusCodeValue,
×
284
                ],
×
285
            ],
×
286
        ]);
×
287
    }
288

289
    /**
290
     * Test config for api keys.
291
     */
292
    public function testInvalidApiKeysConfig(): void
293
    {
294
        $this->expectExceptionMessage('The api keys "key" is not valid according to the pattern enforced by OpenAPI 3.1 ^[a-zA-Z0-9._-]+$.');
×
295
        $exampleConfig = [
×
296
            'name' => 'Authorization',
×
297
            'type' => 'query',
×
298
        ];
×
299

300
        $config = $this->processor->processConfiguration($this->configuration, [
×
301
            'api_platform' => [
×
302
                'swagger' => [
×
303
                    'api_keys' => ['Some Authorization name, like JWT' => $exampleConfig, 'Another-Auth' => $exampleConfig],
×
304
                ],
×
305
            ],
×
306
        ]);
×
307
    }
308

309
    /**
310
     * Test config for api keys.
311
     */
312
    public function testApiKeysConfig(): void
313
    {
314
        $exampleConfig = [
×
315
            'name' => 'Authorization',
×
316
            'type' => 'query',
×
317
        ];
×
318

319
        $config = $this->processor->processConfiguration($this->configuration, [
×
320
            'api_platform' => [
×
321
                'swagger' => [
×
322
                    'api_keys' => ['authorization_name_like_JWT' => $exampleConfig],
×
323
                ],
×
324
            ],
×
325
        ]);
×
326

327
        $this->assertArrayHasKey('api_keys', $config['swagger']);
×
328
        $this->assertSame($exampleConfig, $config['swagger']['api_keys']['authorization_name_like_JWT']);
×
329
    }
330

331
    /**
332
     * Test config for disabled swagger versions.
333
     */
334
    public function testDisabledSwaggerVersionConfig(): void
335
    {
336
        $config = $this->processor->processConfiguration($this->configuration, [
×
337
            'api_platform' => [
×
338
                'enable_swagger' => false,
×
339
                'swagger' => [
×
340
                    'versions' => [3],
×
341
                ],
×
342
            ],
×
343
        ]);
×
344

345
        $this->assertArrayHasKey('versions', $config['swagger']);
×
346
        $this->assertEmpty($config['swagger']['versions']);
×
347
    }
348

349
    /**
350
     * Test config for swagger versions.
351
     */
352
    public function testSwaggerVersionConfig(): void
353
    {
354
        $config = $this->processor->processConfiguration($this->configuration, [
×
355
            'api_platform' => [
×
356
                'swagger' => [
×
357
                    'versions' => [3],
×
358
                ],
×
359
            ],
×
360
        ]);
×
361

362
        $this->assertArrayHasKey('versions', $config['swagger']);
×
363
        $this->assertEquals([3], $config['swagger']['versions']);
×
364

365
        $this->expectException(InvalidConfigurationException::class);
×
366
        $this->expectExceptionMessageMatches('/Only the versions .+ are supported. Got .+./');
×
367

368
        $this->processor->processConfiguration($this->configuration, [
×
369
            'api_platform' => [
×
370
                'swagger' => [
×
371
                    'versions' => [1],
×
372
                ],
×
373
            ],
×
374
        ]);
×
375
    }
376

377
    /**
378
     * Test config for empty title and description.
379
     */
380
    public function testEmptyTitleDescriptionConfig(): void
381
    {
382
        $config = $this->processor->processConfiguration($this->configuration, [
×
383
            'api_platform' => [],
×
384
        ]);
×
385

386
        $this->assertSame('', $config['title']);
×
387
        $this->assertSame('', $config['description']);
×
388
    }
389

390
    public function testEnableElasticsearch(): void
391
    {
392
        $config = $this->processor->processConfiguration($this->configuration, [
×
393
            'api_platform' => [
×
394
                'elasticsearch' => true,
×
395
            ],
×
396
        ]);
×
397

398
        $this->assertTrue($config['elasticsearch']['enabled']);
×
399
    }
400

401
    /**
402
     * Test config for http auth.
403
     */
404
    public function testHttpAuth(): void
405
    {
406
        $config = $this->processor->processConfiguration($this->configuration, [
×
407
            'api_platform' => [
×
408
                'swagger' => [
×
409
                    'http_auth' => ['PAT' => [
×
410
                        'scheme' => 'bearer',
×
411
                        'bearerFormat' => 'JWT',
×
412
                    ]],
×
413
                ],
×
414
            ],
×
415
        ]);
×
416

417
        $this->assertArrayHasKey('http_auth', $config['swagger']);
×
418
        $this->assertSame(['scheme' => 'bearer', 'bearerFormat' => 'JWT'], $config['swagger']['http_auth']['PAT']);
×
419
    }
420

421
    /**
422
     * Test openapi tags.
423
     */
424
    public function testOpenApiTags(): void
425
    {
426
        $config = $this->processor->processConfiguration($this->configuration, [
×
427
            'api_platform' => [
×
428
                'openapi' => [
×
429
                    'tags' => [
×
430
                        ['name' => 'test', 'description' => 'test2'],
×
431
                        ['name' => 'test3'],
×
432
                    ],
×
433
                ],
×
434
            ],
×
435
        ]);
×
436

437
        $this->assertEquals(['name' => 'test3', 'description' => null], $config['openapi']['tags'][1]);
×
438
    }
439
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc