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

api-platform / core / 13203378522

07 Feb 2025 03:56PM UTC coverage: 8.501% (+0.7%) from 7.837%
13203378522

push

github

soyuka
Merge 4.1

111 of 490 new or added lines in 51 files covered. (22.65%)

5590 existing lines in 163 files now uncovered.

13345 of 156987 relevant lines covered (8.5%)

22.88 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,
×
219
                ],
×
220
                'swagger_ui_extra_configuration' => [],
×
221
                'overrideResponses' => true,
×
NEW
222
                'tags' => [],
×
223
            ],
×
224
            'maker' => [
×
225
                'enabled' => true,
×
226
            ],
×
227
            'use_symfony_listeners' => false,
×
228
            'handle_symfony_errors' => false,
×
229
            'enable_link_security' => false,
×
UNCOV
230
            'serializer' => [
×
UNCOV
231
                'hydra_prefix' => null,
×
UNCOV
232
            ],
×
UNCOV
233
        ], $config);
×
234
    }
235

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

NEW
436
        $this->assertEquals(['name' => 'test3', 'description' => null], $config['openapi']['tags'][1]);
×
437
    }
438
}
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