Completed
Push — master ( 5de6c3...432bcd )
by David
05:36 queued 10s
created

testOverrideProfilingFormatter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Http\HttplugBundle\Tests\Unit\DependencyInjection;
4
5
use Http\Client\HttpClient;
6
use Http\Client\Plugin\Vcr\Recorder\InMemoryRecorder;
7
use Http\HttplugBundle\Collector\PluginClientFactoryListener;
8
use Http\HttplugBundle\DependencyInjection\HttplugExtension;
9
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase;
10
use Symfony\Component\DependencyInjection\Reference;
11
use Symfony\Component\HttpKernel\Kernel;
12
use Http\Adapter\Guzzle6\Client;
13
14
/**
15
 * @author David Buchmann <[email protected]>
16
 * @author Tobias Nyholm <[email protected]>
17
 */
18
class HttplugExtensionTest extends AbstractExtensionTestCase
19
{
20
    protected function setUp()
21
    {
22
        parent::setUp();
23
24
        $this->setParameter('kernel.debug', true);
25
    }
26
27
    protected function getContainerExtensions()
28
    {
29
        return [
30
            new HttplugExtension(),
31
        ];
32
    }
33
34
    public function testConfigLoadDefault()
35
    {
36
        $this->load();
37
38
        foreach (['client', 'message_factory', 'uri_factory', 'stream_factory'] as $type) {
39
            $this->assertContainerBuilderHasAlias("httplug.$type", "httplug.$type.default");
40
        }
41
    }
42
43
    public function testConfigLoadClass()
44
    {
45
        $this->load([
46
            'classes' => [
47
                'client' => Client::class,
48
            ],
49
        ]);
50
51
        $this->assertContainerBuilderHasService('httplug.client.default', Client::class);
52
    }
53
54
    public function testConfigLoadService()
55
    {
56
        $this->load([
57
            'main_alias' => [
58
                'client' => 'my_client_service',
59
                'message_factory' => 'my_message_factory_service',
60
                'uri_factory' => 'my_uri_factory_service',
61
                'stream_factory' => 'my_stream_factory_service',
62
            ],
63
        ]);
64
65
        foreach (['client', 'message_factory', 'uri_factory', 'stream_factory'] as $type) {
66
            $this->assertContainerBuilderHasAlias("httplug.$type", "my_{$type}_service");
67
        }
68
    }
69
70
    public function testClientPlugins()
71
    {
72
        $this->load([
73
            'clients' => [
74
                'acme' => [
75
                    'factory' => 'httplug.factory.curl',
76
                    'plugins' => [
77
                        [
78
                            'decoder' => [
79
                                'use_content_encoding' => false,
80
                            ],
81
                        ],
82
                        'httplug.plugin.redirect',
83
                        [
84
                            'add_host' => [
85
                                'host' => 'http://localhost:8000',
86
                            ],
87
                        ],
88
                        [
89
                            'content_type' => [
90
                                'skip_detection' => true,
91
                            ],
92
                        ],
93
                        [
94
                            'header_append' => [
95
                                'headers' => ['X-FOO' => 'bar'],
96
                            ],
97
                        ],
98
                        [
99
                            'header_defaults' => [
100
                                'headers' => ['X-FOO' => 'bar'],
101
                            ],
102
                        ],
103
                        [
104
                            'header_set' => [
105
                                'headers' => ['X-FOO' => 'bar'],
106
                            ],
107
                        ],
108
                        [
109
                            'header_remove' => [
110
                                'headers' => ['X-FOO'],
111
                            ],
112
                        ],
113
                        [
114
                            'query_defaults' => [
115
                                'parameters' => ['locale' => 'en'],
116
                            ],
117
                        ],
118
                        [
119
                            'authentication' => [
120
                                'my_basic' => [
121
                                    'type' => 'basic',
122
                                    'username' => 'foo',
123
                                    'password' => 'bar',
124
                                ],
125
                            ],
126
                        ],
127
                        [
128
                            'cache' => [
129
                                'cache_pool' => 'my_cache_pool',
130
                            ],
131
                        ],
132
                    ],
133
                ],
134
            ],
135
        ]);
136
137
        $plugins = [
138
            'httplug.client.acme.plugin.decoder',
139
            'httplug.plugin.redirect',
140
            'httplug.client.acme.plugin.add_host',
141
            'httplug.client.acme.plugin.content_type',
142
            'httplug.client.acme.plugin.header_append',
143
            'httplug.client.acme.plugin.header_defaults',
144
            'httplug.client.acme.plugin.header_set',
145
            'httplug.client.acme.plugin.header_remove',
146
            'httplug.client.acme.plugin.query_defaults',
147
            'httplug.client.acme.authentication.my_basic',
148
            'httplug.client.acme.plugin.cache',
149
        ];
150
        $pluginReferences = array_map(function ($id) {
151
            return new Reference($id);
152
        }, $plugins);
153
154
        $this->assertContainerBuilderHasService('httplug.client.acme');
155
        foreach ($plugins as $id) {
156
            $this->assertContainerBuilderHasService($id);
157
        }
158
        $this->assertContainerBuilderHasServiceDefinitionWithArgument('httplug.client.acme', 1, $pluginReferences);
159
        $this->assertContainerBuilderHasService('httplug.client.mock');
160
    }
161
162
    /**
163
     * @group legacy
164
     */
165 View Code Duplication
    public function testNoProfilingWhenToolbarIsDisabled()
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...
166
    {
167
        $this->load(
168
            [
169
                'toolbar' => [
170
                    'enabled' => false,
171
                ],
172
                'clients' => [
173
                    'acme' => [
174
                        'factory' => 'httplug.factory.curl',
175
                        'plugins' => ['foo'],
176
                    ],
177
                ],
178
            ]
179
        );
180
181
        $this->verifyProfilingDisabled();
182
    }
183
184 View Code Duplication
    public function testNoProfilingWhenNotInDebugMode()
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...
185
    {
186
        $this->setParameter('kernel.debug', false);
187
        $this->load(
188
            [
189
                'clients' => [
190
                    'acme' => [
191
                        'factory' => 'httplug.factory.curl',
192
                        'plugins' => ['foo'],
193
                    ],
194
                ],
195
            ]
196
        );
197
198
        $this->verifyProfilingDisabled();
199
    }
200
201
    /**
202
     * @group legacy
203
     */
204 View Code Duplication
    public function testProfilingWhenToolbarIsSpecificallyOn()
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...
205
    {
206
        $this->setParameter('kernel.debug', false);
207
        $this->load(
208
            [
209
                'toolbar' => [
210
                    'enabled' => true,
211
                ],
212
                'clients' => [
213
                    'acme' => [
214
                        'factory' => 'httplug.factory.curl',
215
                        'plugins' => ['foo'],
216
                    ],
217
                ],
218
            ]
219
        );
220
221
        $this->assertContainerBuilderHasService(PluginClientFactoryListener::class);
222
    }
223
224
    public function testOverrideProfilingFormatter()
225
    {
226
        $this->load(
227
            [
228
                'profiling' => [
229
                    'formatter' => 'acme.formatter',
230
                ],
231
            ]
232
        );
233
234
        $def = $this->container->findDefinition('httplug.collector.formatter');
235
        $this->assertEquals('acme.formatter', (string) $def->getArgument(0));
236
    }
237
238
    public function testCachePluginConfigCacheKeyGeneratorReference()
239
    {
240
        $this->load([
241
            'plugins' => [
242
                'cache' => [
243
                    'cache_pool' => 'my_cache_pool',
244
                    'config' => [
245
                        'cache_key_generator' => 'header_cache_key_generator',
246
                    ],
247
                ],
248
            ],
249
        ]);
250
251
        $cachePlugin = $this->container->findDefinition('httplug.plugin.cache');
252
253
        $config = $cachePlugin->getArgument(2);
254
        $this->assertArrayHasKey('cache_key_generator', $config);
255
        $this->assertInstanceOf(Reference::class, $config['cache_key_generator']);
256
        $this->assertSame('header_cache_key_generator', (string) $config['cache_key_generator']);
257
    }
258
259
    public function testContentTypePluginAllowedOptions()
260
    {
261
        $this->load([
262
            'clients' => [
263
                'acme' => [
264
                    'plugins' => [
265
                        [
266
                            'content_type' => [
267
                                'skip_detection' => true,
268
                                'size_limit' => 200000,
269
                            ],
270
                        ],
271
                    ],
272
                ],
273
            ],
274
        ]);
275
276
        $cachePlugin = $this->container->findDefinition('httplug.client.acme.plugin.content_type');
277
278
        $config = $cachePlugin->getArgument(0);
279
        $this->assertEquals([
280
            'skip_detection' => true,
281
            'size_limit' => 200000,
282
        ], $config);
283
    }
284
285
    public function testUsingServiceKeyForClients()
286
    {
287
        $this->load([
288
            'clients' => [
289
                'acme' => [
290
                    'service' => 'my_custom_client',
291
                ],
292
            ],
293
        ]);
294
295
        $client = $this->container->getAlias('httplug.client.acme.client');
296
        $this->assertEquals('my_custom_client', (string) $client);
297
        $this->assertFalse($client->isPublic());
298
    }
299
300
    private function verifyProfilingDisabled()
301
    {
302
        $def = $this->container->findDefinition('httplug.client');
303
        $this->assertTrue(is_subclass_of($def->getClass(), HttpClient::class));
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Http\Client\HttpClient::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
304
        $arguments = $def->getArguments();
305
306
        if (isset($arguments[3])) {
307
            $this->assertEmpty(
308
                $arguments[3],
309
                'Parameter 3 to the PluginClient must not contain any debug_plugin information when profiling is disabled'
310
            );
311
        }
312
    }
313
314
    public function testClientShouldHaveDefaultVisibility()
315
    {
316
        $this->load([
317
            'clients' => [
318
                'acme' => [],
319
            ],
320
        ]);
321
322
        $this->assertContainerBuilderHasService('httplug.client.acme');
323
324
        if (version_compare(Kernel::VERSION, '3.4', '>=')) {
325
            // Symfony made services private by default starting from 3.4
326
            $this->assertTrue($this->container->getDefinition('httplug.client.acme')->isPublic());
327
            $this->assertTrue($this->container->getDefinition('httplug.client.acme')->isPrivate());
328
        } else {
329
            // Legacy Symfony
330
            $this->assertTrue($this->container->getDefinition('httplug.client.acme')->isPublic());
331
        }
332
    }
333
334 View Code Duplication
    public function testFlexibleClientShouldBePrivateByDefault()
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...
335
    {
336
        $this->load([
337
            'clients' => [
338
                'acme' => [
339
                    'flexible_client' => true,
340
                ],
341
            ],
342
        ]);
343
344
        $this->assertContainerBuilderHasService('httplug.client.acme');
345
        $this->assertFalse($this->container->getDefinition('httplug.client.acme.flexible')->isPublic());
346
    }
347
348 View Code Duplication
    public function testHttpMethodsClientShouldBePrivateByDefault()
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...
349
    {
350
        $this->load([
351
            'clients' => [
352
                'acme' => [
353
                    'http_methods_client' => true,
354
                ],
355
            ],
356
        ]);
357
358
        $this->assertContainerBuilderHasService('httplug.client.acme');
359
        $this->assertFalse($this->container->getDefinition('httplug.client.acme.http_methods')->isPublic());
360
    }
361
362 View Code Duplication
    public function testBatchClientShouldBePrivateByDefault()
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...
363
    {
364
        $this->load([
365
            'clients' => [
366
                'acme' => [
367
                    'batch_client' => true,
368
                ],
369
            ],
370
        ]);
371
372
        $this->assertContainerBuilderHasService('httplug.client.acme');
373
        $this->assertFalse($this->container->getDefinition('httplug.client.acme.batch_client')->isPublic());
374
    }
375
376 View Code Duplication
    public function testClientCanBePublic()
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...
377
    {
378
        $this->load([
379
            'clients' => [
380
                'acme' => [
381
                    'public' => true,
382
                ],
383
            ],
384
        ]);
385
386
        $this->assertContainerBuilderHasService('httplug.client.acme');
387
        $this->assertTrue($this->container->getDefinition('httplug.client.acme')->isPublic());
388
389
        if (version_compare(Kernel::VERSION, '3.4', '>=')) {
390
            // Symfony made services private by default starting from 3.4
391
            $this->assertFalse($this->container->getDefinition('httplug.client.acme')->isPrivate());
392
        }
393
    }
394
395 View Code Duplication
    public function testFlexibleClientCanBePublic()
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...
396
    {
397
        $this->load([
398
            'clients' => [
399
                'acme' => [
400
                    'public' => true,
401
                    'flexible_client' => true,
402
                ],
403
            ],
404
        ]);
405
406
        $this->assertContainerBuilderHasService('httplug.client.acme');
407
        $this->assertTrue($this->container->getDefinition('httplug.client.acme.flexible')->isPublic());
408
409
        if (version_compare(Kernel::VERSION, '3.4', '>=')) {
410
            // Symfony made services private by default starting from 3.4
411
            $this->assertFalse($this->container->getDefinition('httplug.client.acme.flexible')->isPrivate());
412
        }
413
    }
414
415 View Code Duplication
    public function testHttpMethodsClientCanBePublic()
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...
416
    {
417
        $this->load([
418
            'clients' => [
419
                'acme' => [
420
                    'public' => true,
421
                    'http_methods_client' => true,
422
                ],
423
            ],
424
        ]);
425
426
        $this->assertContainerBuilderHasService('httplug.client.acme');
427
        $this->assertTrue($this->container->getDefinition('httplug.client.acme.http_methods')->isPublic());
428
429
        if (version_compare(Kernel::VERSION, '3.4', '>=')) {
430
            // Symfony made services private by default starting from 3.4
431
            $this->assertFalse($this->container->getDefinition('httplug.client.acme.http_methods')->isPrivate());
432
        }
433
    }
434
435 View Code Duplication
    public function testBatchClientCanBePublic()
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...
436
    {
437
        $this->load([
438
            'clients' => [
439
                'acme' => [
440
                    'public' => true,
441
                    'batch_client' => true,
442
                ],
443
            ],
444
        ]);
445
446
        $this->assertContainerBuilderHasService('httplug.client.acme');
447
        $this->assertTrue($this->container->getDefinition('httplug.client.acme.batch_client')->isPublic());
448
449
        if (version_compare(Kernel::VERSION, '3.4', '>=')) {
450
            // Symfony made services private by default starting from 3.4
451
            $this->assertFalse($this->container->getDefinition('httplug.client.acme.batch_client')->isPrivate());
452
        }
453
    }
454
455
    /**
456
     * @dataProvider provideVcrPluginConfig
457
     * @group vcr-plugin
458
     */
459
    public function testVcrPluginConfiguration(array $config, array $services, array $arguments = [])
460
    {
461
        if (!class_exists(InMemoryRecorder::class)) {
462
            $this->markTestSkipped('VCR plugin is not installed.');
463
        }
464
465
        $prefix = 'httplug.client.acme.vcr';
466
        $this->load(['clients' => ['acme' => ['plugins' => [['vcr' => $config]]]]]);
467
        $this->assertContainerBuilderHasService('httplug.plugin.vcr.recorder.in_memory', InMemoryRecorder::class);
468
469
        foreach ($services as $service) {
470
            $this->assertContainerBuilderHasService($prefix.'.'.$service);
471
        }
472
473
        foreach ($arguments as $id => $args) {
474
            foreach ($args as $index => $value) {
475
                $this->assertContainerBuilderHasServiceDefinitionWithArgument($prefix.'.'.$id, $index, $value);
476
            }
477
        }
478
    }
479
480
    /**
481
     * @group vcr-plugin
482
     */
483
    public function testIsNotLoadedUnlessNeeded()
484
    {
485
        if (!class_exists(InMemoryRecorder::class)) {
486
            $this->markTestSkipped('VCR plugin is not installed.');
487
        }
488
489
        $this->load(['clients' => ['acme' => ['plugins' => []]]]);
490
        $this->assertContainerBuilderNotHasService('httplug.plugin.vcr.recorder.in_memory');
491
    }
492
493
    public function provideVcrPluginConfig()
494
    {
495
        $config = [
496
            'mode' => 'record',
497
            'recorder' => 'in_memory',
498
            'naming_strategy' => 'app.naming_strategy',
499
        ];
500
        yield [$config, ['record']];
501
502
        $config['mode'] = 'replay';
503
        yield [$config, ['replay']];
504
505
        $config['mode'] = 'replay_or_record';
506
        yield [$config, ['replay', 'record']];
507
508
        $config['recorder'] = 'filesystem';
509
        $config['fixtures_directory'] = __DIR__;
510
        unset($config['naming_strategy']);
511
512
        yield [$config, ['replay', 'record', 'recorder', 'naming_strategy'], ['replay' => [2 => false]]];
513
514
        $config['naming_strategy_options'] = [
515
            'hash_headers' => ['X-FOO'],
516
            'hash_body_methods' => ['PATCH'],
517
        ];
518
519
        yield [
520
            $config,
521
            ['replay', 'record', 'recorder', 'naming_strategy'],
522
            ['naming_strategy' => [$config['naming_strategy_options']]],
523
        ];
524
    }
525
}
526