Completed
Push — master ( dd63ce...bad327 )
by David
14:41
created

testIsNotLoadedUnlessNeeded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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