Completed
Push — master ( baba12...502b0f )
by Andreas
08:34
created

DoctrineExtensionTest::testShardManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 23
rs 9.552
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection;
4
5
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
6
use Doctrine\Bundle\DoctrineBundle\Tests\Builder\BundleConfigurationBuilder;
7
use Doctrine\Common\Persistence\ManagerRegistry;
8
use Doctrine\Common\Persistence\ObjectManager;
9
use Doctrine\Common\Proxy\AbstractProxyFactory;
10
use Doctrine\DBAL\Connection;
11
use Doctrine\DBAL\Driver\Connection as DriverConnection;
12
use Doctrine\ORM\EntityManagerInterface;
13
use PHPUnit\Framework\TestCase;
14
use Symfony\Component\Cache\Adapter\ArrayAdapter;
15
use Symfony\Component\Cache\DoctrineProvider;
16
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\Definition;
19
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
20
use Symfony\Component\DependencyInjection\Reference;
21
use Symfony\Component\Messenger\MessageBusInterface;
22
23
class DoctrineExtensionTest extends TestCase
24
{
25
    public function testAutowiringAlias()
26
    {
27
        $container = $this->getContainer();
28
        $extension = new DoctrineExtension();
29
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
30
31
        $extension->load([$config], $container);
32
33
        $expectedAliases = [
34
            DriverConnection::class => 'database_connection',
35
            Connection::class => 'database_connection',
36
            ManagerRegistry::class => 'doctrine',
37
            ObjectManager::class => 'doctrine.orm.entity_manager',
38
            EntityManagerInterface::class => 'doctrine.orm.entity_manager',
39
        ];
40
41
        foreach ($expectedAliases as $id => $target) {
42
            $this->assertTrue($container->hasAlias($id), sprintf('The container should have a `%s` alias for autowiring support.', $id));
43
44
            $alias = $container->getAlias($id);
45
            $this->assertEquals($target, (string) $alias, sprintf('The autowiring for `%s` should use `%s`.', $id, $target));
46
            $this->assertFalse($alias->isPublic(), sprintf('The autowiring alias for `%s` should be private.', $id, $target));
47
        }
48
    }
49
50
    public function testPublicServicesAndAliases()
51
    {
52
        $container = $this->getContainer();
53
        $extension = new DoctrineExtension();
54
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
55
56
        $extension->load([$config], $container);
57
58
        $this->assertTrue($container->getDefinition('doctrine')->isPublic());
59
        $this->assertTrue($container->getAlias('doctrine.orm.entity_manager')->isPublic());
60
        $this->assertTrue($container->getAlias('database_connection')->isPublic());
61
    }
62
63
    public function testDbalGenerateDefaultConnectionConfiguration()
64
    {
65
        $container = $this->getContainer();
66
        $extension = new DoctrineExtension();
67
68
        $container->registerExtension($extension);
69
70
        $extension->load([['dbal' => []]], $container);
71
72
        // doctrine.dbal.default_connection
73
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3));
74
        $this->assertEquals('default', $container->getParameter('doctrine.default_connection'));
75
        $this->assertEquals('root', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['user']);
76
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['password']);
77
        $this->assertEquals('localhost', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['host']);
78
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['port']);
79
        $this->assertEquals('pdo_mysql', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driver']);
80
        $this->assertEquals([], $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driverOptions']);
81
    }
82
83
    public function testDbalOverrideDefaultConnection()
84
    {
85
        $container = $this->getContainer();
86
        $extension = new DoctrineExtension();
87
88
        $container->registerExtension($extension);
89
90
        $extension->load([[], ['dbal' => ['default_connection' => 'foo']], []], $container);
91
92
        // doctrine.dbal.default_connection
93
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3), '->load() overrides existing configuration options');
94
        $this->assertEquals('foo', $container->getParameter('doctrine.default_connection'), '->load() overrides existing configuration options');
95
    }
96
97
    /**
98
     * @expectedException \LogicException
99
     * @expectedExceptionMessage Configuring the ORM layer requires to configure the DBAL layer as well.
100
     */
101
    public function testOrmRequiresDbal()
102
    {
103
        $extension = new DoctrineExtension();
104
105
        $extension->load([['orm' => ['auto_mapping' => true]]], $this->getContainer());
106
    }
107
108
    public function getAutomappingConfigurations()
109
    {
110
        return [
111
            [
112
                [
113
                    'em1' => [
114
                        'mappings' => ['YamlBundle' => null],
115
                    ],
116
                    'em2' => [
117
                        'mappings' => ['XmlBundle' => null],
118
                    ],
119
                ],
120
            ],
121
            [
122
                [
123
                    'em1' => ['auto_mapping' => true],
124
                    'em2' => [
125
                        'mappings' => ['XmlBundle' => null],
126
                    ],
127
                ],
128
            ],
129
            [
130
                [
131
                    'em1' => [
132
                        'auto_mapping' => true,
133
                        'mappings' => ['YamlBundle' => null],
134
                    ],
135
                    'em2' => [
136
                        'mappings' => ['XmlBundle' => null],
137
                    ],
138
                ],
139
            ],
140
        ];
141
    }
142
143
    /**
144
     * @dataProvider getAutomappingConfigurations
145
     */
146
    public function testAutomapping(array $entityManagers)
147
    {
148
        $extension = new DoctrineExtension();
149
150
        $container = $this->getContainer([
0 ignored issues
show
Documentation introduced by
array('YamlBundle', 'XmlBundle') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151
            'YamlBundle',
152
            'XmlBundle',
153
        ]);
154
155
        $extension->load(
156
            [
157
                [
158
                    'dbal' => [
159
                        'default_connection' => 'cn1',
160
                        'connections' => [
161
                            'cn1' => [],
162
                            'cn2' => [],
163
                        ],
164
                    ],
165
                    'orm' => ['entity_managers' => $entityManagers],
166
                ],
167
            ],
168
            $container
169
        );
170
171
        $configEm1 = $container->getDefinition('doctrine.orm.em1_configuration');
172
        $configEm2 = $container->getDefinition('doctrine.orm.em2_configuration');
173
174
        $this->assertContains(
175
            [
176
                'setEntityNamespaces',
177
                [
178
                    ['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'],
179
                ],
180
            ],
181
            $configEm1->getMethodCalls()
182
        );
183
184
        $this->assertContains(
185
            [
186
                'setEntityNamespaces',
187
                [
188
                    ['XmlBundle' => 'Fixtures\Bundles\XmlBundle\Entity'],
189
                ],
190
            ],
191
            $configEm2->getMethodCalls()
192
        );
193
    }
194
195
    public function testDbalLoad()
196
    {
197
        $container = $this->getContainer();
198
        $extension = new DoctrineExtension();
199
200
        $extension->load([
201
            ['dbal' => ['connections' => ['default' => ['password' => 'foo']]]],
202
            [],
203
            ['dbal' => ['default_connection' => 'foo']],
204
            [],
205
        ], $container);
206
207
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
208
209
        $this->assertEquals('foo', $config['password']);
210
        $this->assertEquals('root', $config['user']);
211
    }
212
213
    public function testDbalWrapperClass()
214
    {
215
        $container = $this->getContainer();
216
        $extension = new DoctrineExtension();
217
218
        $extension->load(
219
            [
220
                [
221
                    'dbal' => [
222
                        'connections' => [
223
                            'default' => ['password' => 'foo', 'wrapper_class' => TestWrapperClass::class],
224
                            'second' => ['password' => 'boo'],
225
                        ],
226
                    ],
227
                ],
228
                [],
229
                ['dbal' => ['default_connection' => 'foo']],
230
                [],
231
            ],
232
            $container
233
        );
234
235
        $this->assertEquals(TestWrapperClass::class, $container->getDefinition('doctrine.dbal.default_connection')->getClass());
236
        $this->assertNull($container->getDefinition('doctrine.dbal.second_connection')->getClass());
237
    }
238
239
    public function testDependencyInjectionConfigurationDefaults()
240
    {
241
        $container = $this->getContainer();
242
        $extension = new DoctrineExtension();
243
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
244
245
        $extension->load([$config], $container);
246
247
        $this->assertFalse($container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
248
        $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration.class'));
249
        $this->assertEquals('Doctrine\ORM\EntityManager', $container->getParameter('doctrine.orm.entity_manager.class'));
250
        $this->assertEquals('Proxies', $container->getParameter('doctrine.orm.proxy_namespace'));
251
        $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.orm.cache.array.class'));
252
        $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.orm.cache.apc.class'));
253
        $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.orm.cache.memcache.class'));
254
        $this->assertEquals('localhost', $container->getParameter('doctrine.orm.cache.memcache_host'));
255
        $this->assertEquals('11211', $container->getParameter('doctrine.orm.cache.memcache_port'));
256
        $this->assertEquals('Memcache', $container->getParameter('doctrine.orm.cache.memcache_instance.class'));
257
        $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.orm.cache.xcache.class'));
258
        $this->assertEquals('Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class'));
259
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.orm.metadata.annotation.class'));
260
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver', $container->getParameter('doctrine.orm.metadata.xml.class'));
261
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver', $container->getParameter('doctrine.orm.metadata.yml.class'));
262
263
        // second-level cache
264
        $this->assertEquals('Doctrine\ORM\Cache\DefaultCacheFactory', $container->getParameter('doctrine.orm.second_level_cache.default_cache_factory.class'));
265
        $this->assertEquals('Doctrine\ORM\Cache\Region\DefaultRegion', $container->getParameter('doctrine.orm.second_level_cache.default_region.class'));
266
        $this->assertEquals('Doctrine\ORM\Cache\Region\FileLockRegion', $container->getParameter('doctrine.orm.second_level_cache.filelock_region.class'));
267
        $this->assertEquals('Doctrine\ORM\Cache\Logging\CacheLoggerChain', $container->getParameter('doctrine.orm.second_level_cache.logger_chain.class'));
268
        $this->assertEquals('Doctrine\ORM\Cache\Logging\StatisticsCacheLogger', $container->getParameter('doctrine.orm.second_level_cache.logger_statistics.class'));
269
        $this->assertEquals('Doctrine\ORM\Cache\CacheConfiguration', $container->getParameter('doctrine.orm.second_level_cache.cache_configuration.class'));
270
        $this->assertEquals('Doctrine\ORM\Cache\RegionsConfiguration', $container->getParameter('doctrine.orm.second_level_cache.regions_configuration.class'));
271
272
        $config = BundleConfigurationBuilder::createBuilder()
273
            ->addBaseConnection()
274
            ->addEntityManager([
275
                'proxy_namespace' => 'MyProxies',
276
                'auto_generate_proxy_classes' => true,
277
                'default_entity_manager' => 'default',
278
                'entity_managers' => [
279
                    'default' => [
280
                        'mappings' => ['YamlBundle' => []],
281
                    ],
282
                ],
283
            ])
284
            ->build();
285
286
        $container = $this->getContainer();
287
        $extension->load([$config], $container);
288
        $this->compileContainer($container);
289
290
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
291
292
        $args = $definition->getArguments();
293
        $this->assertEquals('pdo_mysql', $args[0]['driver']);
294
        $this->assertEquals('localhost', $args[0]['host']);
295
        $this->assertEquals('root', $args[0]['user']);
296
        $this->assertEquals('doctrine.dbal.default_connection.configuration', (string) $args[1]);
297
        $this->assertEquals('doctrine.dbal.default_connection.event_manager', (string) $args[2]);
298
        $this->assertCount(0, $definition->getMethodCalls());
0 ignored issues
show
Documentation introduced by
$definition->getMethodCalls() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
299
300
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
301
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
302
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
303
304
        $this->assertEquals(['default' => 'doctrine.orm.default_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
305
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
306
307
        $arguments = $definition->getArguments();
308
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
309
        $this->assertEquals('doctrine.dbal.default_connection', (string) $arguments[0]);
310
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
311
        $this->assertEquals('doctrine.orm.default_configuration', (string) $arguments[1]);
312
313
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
314
        $calls      = array_values($definition->getMethodCalls());
315
        $this->assertEquals(['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'], $calls[0][1][0]);
316
        $this->assertEquals('doctrine.orm.default_metadata_cache', (string) $calls[1][1][0]);
317
        $this->assertEquals('doctrine.orm.default_query_cache', (string) $calls[2][1][0]);
318
        $this->assertEquals('doctrine.orm.default_result_cache', (string) $calls[3][1][0]);
319
320
        $this->assertEquals('doctrine.orm.naming_strategy.default', (string) $calls[10][1][0]);
321
        $this->assertEquals('doctrine.orm.quote_strategy.default', (string) $calls[11][1][0]);
322
        $this->assertEquals('doctrine.orm.default_entity_listener_resolver', (string) $calls[12][1][0]);
323
324
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
325
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
326
        $arguments = $definition->getArguments();
327
        $this->assertInstanceOf(Reference::class, $arguments[0]);
328
        $this->assertEquals('cache.system', (string) $arguments[0]);
329
330
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_query_cache'));
331
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
332
        $arguments = $definition->getArguments();
333
        $this->assertInstanceOf(Reference::class, $arguments[0]);
334
        $this->assertEquals('cache.app', (string) $arguments[0]);
335
336
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_result_cache'));
337
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
338
        $arguments = $definition->getArguments();
339
        $this->assertInstanceOf(Reference::class, $arguments[0]);
340
        $this->assertEquals('cache.app', (string) $arguments[0]);
341
    }
342
343
    public function testUseSavePointsAddMethodCallToAddSavepointsToTheConnection()
344
    {
345
        $container = $this->getContainer();
346
        $extension = new DoctrineExtension();
347
348
        $extension->load([[
349
            'dbal' => [
350
                'connections' => [
351
                    'default' => ['password' => 'foo', 'use_savepoints' => true],
352
                ],
353
            ],
354
        ],
355
        ], $container);
356
357
        $calls = $container->getDefinition('doctrine.dbal.default_connection')->getMethodCalls();
358
        $this->assertCount(1, $calls);
0 ignored issues
show
Documentation introduced by
$calls is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
359
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
360
        $this->assertTrue($calls[0][1][0]);
361
    }
362
363
    public function testAutoGenerateProxyClasses()
364
    {
365
        $container = $this->getContainer();
366
        $extension = new DoctrineExtension();
367
368
        $config = BundleConfigurationBuilder::createBuilder()
369
            ->addBaseConnection()
370
            ->addEntityManager([
371
                'proxy_namespace' => 'MyProxies',
372
                'auto_generate_proxy_classes' => 'eval',
373
                'default_entity_manager' => 'default',
374
                'entity_managers' => [
375
                    'default' => [
376
                        'mappings' => ['YamlBundle' => []],
377
                    ],
378
                ],
379
            ])
380
            ->build();
381
382
        $extension->load([$config], $container);
383
384
        $this->assertEquals(AbstractProxyFactory::AUTOGENERATE_EVAL, $container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
385
    }
386
387
    public function testSingleEntityManagerWithDefaultConfiguration()
388
    {
389
        $container = $this->getContainer();
390
        $extension = new DoctrineExtension();
391
392
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
393
394
        $extension->load([$configurationArray], $container);
395
        $this->compileContainer($container);
396
397
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
398
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
399
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
400
401
        $this->assertDICConstructorArguments($definition, [
402
            new Reference('doctrine.dbal.default_connection'),
403
            new Reference('doctrine.orm.default_configuration'),
404
        ]);
405
    }
406
407
    public function testSingleEntityManagerWithDefaultSecondLevelCacheConfiguration()
408
    {
409
        $container = $this->getContainer();
410
        $extension = new DoctrineExtension();
411
412
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
413
            ->addBaseSecondLevelCache()
414
            ->build();
415
416
        $extension->load([$configurationArray], $container);
417
        $this->compileContainer($container);
418
419
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
420
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
421
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
422
423
        $this->assertDICConstructorArguments($definition, [
424
            new Reference('doctrine.dbal.default_connection'),
425
            new Reference('doctrine.orm.default_configuration'),
426
        ]);
427
428
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
429
        $this->assertEquals('%doctrine.orm.second_level_cache.default_cache_factory.class%', $slcDefinition->getClass());
430
    }
431
432
    public function testSingleEntityManagerWithCustomSecondLevelCacheConfiguration()
433
    {
434
        $container = $this->getContainer();
435
        $extension = new DoctrineExtension();
436
437
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
438
            ->addSecondLevelCache([
439
                'region_cache_driver' => ['type' => 'service', 'id' => 'my_cache'],
440
                'regions' => [
441
                    'hour_region' => ['lifetime' => 3600],
442
                ],
443
                'factory' => 'YamlBundle\Cache\MyCacheFactory',
444
            ])
445
            ->build();
446
447
        $extension->load([$configurationArray], $container);
448
        $this->compileContainer($container);
449
450
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
451
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
452
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
453
454
        $this->assertDICConstructorArguments($definition, [
455
            new Reference('doctrine.dbal.default_connection'),
456
            new Reference('doctrine.orm.default_configuration'),
457
        ]);
458
459
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
460
        $this->assertEquals('YamlBundle\Cache\MyCacheFactory', $slcDefinition->getClass());
461
    }
462
463 View Code Duplication
    public function testBundleEntityAliases()
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...
464
    {
465
        $container = $this->getContainer();
466
        $extension = new DoctrineExtension();
467
468
        $config        = BundleConfigurationBuilder::createBuilder()
469
             ->addBaseConnection()
470
             ->build();
471
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => []]]]];
472
        $extension->load([$config], $container);
473
474
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
475
        $this->assertDICDefinitionMethodCallOnce(
476
            $definition,
477
            'setEntityNamespaces',
478
            [['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity']]
479
        );
480
    }
481
482 View Code Duplication
    public function testOverwriteEntityAliases()
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...
483
    {
484
        $container = $this->getContainer();
485
        $extension = new DoctrineExtension();
486
487
        $config        = BundleConfigurationBuilder::createBuilder()
488
             ->addBaseConnection()
489
             ->build();
490
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => ['alias' => 'yml']]]]];
491
        $extension->load([$config], $container);
492
493
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
494
        $this->assertDICDefinitionMethodCallOnce(
495
            $definition,
496
            'setEntityNamespaces',
497
            [['yml' => 'Fixtures\Bundles\YamlBundle\Entity']]
498
        );
499
    }
500
501
    public function testYamlBundleMappingDetection()
502
    {
503
        $container = $this->getContainer('YamlBundle');
504
        $extension = new DoctrineExtension();
505
506
        $config = BundleConfigurationBuilder::createBuilder()
507
            ->addBaseConnection()
508
            ->addBaseEntityManager()
509
            ->build();
510
        $extension->load([$config], $container);
511
512
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
513
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
514
            new Reference('doctrine.orm.default_yml_metadata_driver'),
515
            'Fixtures\Bundles\YamlBundle\Entity',
516
        ]);
517
    }
518
519 View Code Duplication
    public function testXmlBundleMappingDetection()
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...
520
    {
521
        $container = $this->getContainer('XmlBundle');
522
        $extension = new DoctrineExtension();
523
524
        $config = BundleConfigurationBuilder::createBuilder()
525
            ->addBaseConnection()
526
            ->addEntityManager([
527
                'default_entity_manager' => 'default',
528
                'entity_managers' => [
529
                    'default' => [
530
                        'mappings' => [
531
                            'XmlBundle' => [],
532
                        ],
533
                    ],
534
                ],
535
            ])
536
            ->build();
537
        $extension->load([$config], $container);
538
539
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
540
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
541
            new Reference('doctrine.orm.default_xml_metadata_driver'),
542
            'Fixtures\Bundles\XmlBundle\Entity',
543
        ]);
544
    }
545
546 View Code Duplication
    public function testAnnotationsBundleMappingDetection()
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...
547
    {
548
        $container = $this->getContainer('AnnotationsBundle');
549
        $extension = new DoctrineExtension();
550
551
        $config = BundleConfigurationBuilder::createBuilder()
552
            ->addBaseConnection()
553
            ->addEntityManager([
554
                'default_entity_manager' => 'default',
555
                'entity_managers' => [
556
                    'default' => [
557
                        'mappings' => [
558
                            'AnnotationsBundle' => [],
559
                        ],
560
                    ],
561
                ],
562
            ])
563
            ->build();
564
        $extension->load([$config], $container);
565
566
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
567
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
568
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
569
            'Fixtures\Bundles\AnnotationsBundle\Entity',
570
        ]);
571
    }
572
573
    public function testOrmMergeConfigs()
574
    {
575
        $container = $this->getContainer(['XmlBundle', 'AnnotationsBundle']);
0 ignored issues
show
Documentation introduced by
array('XmlBundle', 'AnnotationsBundle') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
576
        $extension = new DoctrineExtension();
577
578
        $config1 = BundleConfigurationBuilder::createBuilder()
579
            ->addBaseConnection()
580
            ->addEntityManager([
581
                'auto_generate_proxy_classes' => true,
582
                'default_entity_manager' => 'default',
583
                'entity_managers' => [
584
                    'default' => [
585
                        'mappings' => [
586
                            'AnnotationsBundle' => [],
587
                        ],
588
                    ],
589
                ],
590
            ])
591
            ->build();
592
        $config2 = BundleConfigurationBuilder::createBuilder()
593
            ->addBaseConnection()
594
            ->addEntityManager([
595
                'auto_generate_proxy_classes' => false,
596
                'default_entity_manager' => 'default',
597
                'entity_managers' => [
598
                    'default' => [
599
                        'mappings' => [
600
                            'XmlBundle' => [],
601
                        ],
602
                    ],
603
                ],
604
            ])
605
            ->build();
606
        $extension->load([$config1, $config2], $container);
607
608
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
609
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
610
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
611
            'Fixtures\Bundles\AnnotationsBundle\Entity',
612
        ]);
613
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
614
            new Reference('doctrine.orm.default_xml_metadata_driver'),
615
            'Fixtures\Bundles\XmlBundle\Entity',
616
        ]);
617
618
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
619
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setAutoGenerateProxyClasses');
620
621
        $calls = $configDef->getMethodCalls();
622
        foreach ($calls as $call) {
623
            if ($call[0] === 'setAutoGenerateProxyClasses') {
624
                $this->assertFalse($container->getParameterBag()->resolveValue($call[1][0]));
625
                break;
626
            }
627
        }
628
    }
629
630
    public function testAnnotationsBundleMappingDetectionWithVendorNamespace()
631
    {
632
        $container = $this->getContainer('AnnotationsBundle', 'Vendor');
633
        $extension = new DoctrineExtension();
634
635
        $config = BundleConfigurationBuilder::createBuilder()
636
            ->addBaseConnection()
637
            ->addEntityManager([
638
                'default_entity_manager' => 'default',
639
                'entity_managers' => [
640
                    'default' => [
641
                        'mappings' => [
642
                            'AnnotationsBundle' => [],
643
                        ],
644
                    ],
645
                ],
646
            ])
647
            ->build();
648
        $extension->load([$config], $container);
649
650
        $calls = $container->getDefinition('doctrine.orm.default_metadata_driver')->getMethodCalls();
651
        $this->assertEquals('doctrine.orm.default_annotation_metadata_driver', (string) $calls[0][1][0]);
652
        $this->assertEquals('Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]);
653
    }
654
655
    public function testMessengerIntegration()
656
    {
657
        if (! interface_exists(MessageBusInterface::class)) {
658
            $this->markTestSkipped('Symfony Messenger component is not installed');
659
        }
660
661
        $container = $this->getContainer();
662
        $extension = new DoctrineExtension();
663
664
        $config = BundleConfigurationBuilder::createBuilder()
665
            ->addBaseConnection()
666
            ->addEntityManager([
667
                'default_entity_manager' => 'default',
668
                'entity_managers' => [
669
                    'default' => [],
670
                ],
671
            ])
672
            ->build();
673
        $extension->load([$config], $container);
674
675
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_transaction'));
676
        $this->assertCount(1, $middlewarePrototype->getArguments());
0 ignored issues
show
Documentation introduced by
$middlewarePrototype->getArguments() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
677
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_clear_entity_manager'));
678
        $this->assertCount(1, $middlewarePrototype->getArguments());
0 ignored issues
show
Documentation introduced by
$middlewarePrototype->getArguments() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
679
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_ping_connection'));
680
        $this->assertCount(1, $middlewarePrototype->getArguments());
0 ignored issues
show
Documentation introduced by
$middlewarePrototype->getArguments() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
681
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_close_connection'));
682
        $this->assertCount(1, $middlewarePrototype->getArguments());
0 ignored issues
show
Documentation introduced by
$middlewarePrototype->getArguments() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
683
    }
684
685
    /**
686
     * @param array|string $cacheConfig
687
     *
688
     * @group legacy
689
     * @dataProvider deprecatedCacheConfigurationProvider
690
     */
691 View Code Duplication
    public function testDeprecatedCacheConfiguration(string $expectedAliasName, string $expectedAliasTarget, string $cacheName, $cacheConfig) : void
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...
692
    {
693
        $container = $this->getContainer();
694
        $extension = new DoctrineExtension();
695
696
        $config = BundleConfigurationBuilder::createBuilder()
697
            ->addBaseConnection()
698
            ->addEntityManager([$cacheName => $cacheConfig])
699
            ->build();
700
701
        $extension->load([$config], $container);
702
703
        $this->assertTrue($container->hasAlias($expectedAliasName));
704
        $alias = $container->getAlias($expectedAliasName);
705
        $this->assertEquals($expectedAliasTarget, (string) $alias);
706
    }
707
708
    public static function deprecatedCacheConfigurationProvider() : array
709
    {
710
        return [
711
            'metadata_cache_provider' => [
712
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
713
                'expectedAliasTarget' => 'doctrine_cache.providers.metadata_cache',
714
                'cacheName' => 'metadata_cache_driver',
715
                'cacheConfig' => ['cache_provider' => 'metadata_cache'],
716
            ],
717
            'query_cache_provider' => [
718
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
719
                'expectedAliasTarget' => 'doctrine_cache.providers.query_cache',
720
                'cacheName' => 'query_cache_driver',
721
                'cacheConfig' => ['cache_provider' => 'query_cache'],
722
            ],
723
            'result_cache_provider' => [
724
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
725
                'expectedAliasTarget' => 'doctrine_cache.providers.result_cache',
726
                'cacheName' => 'result_cache_driver',
727
                'cacheConfig' => ['cache_provider' => 'result_cache'],
728
            ],
729
730
            'metadata_cache_array' => [
731
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
732
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_metadata_cache',
733
                'cacheName' => 'metadata_cache_driver',
734
                'cacheConfig' => 'array',
735
            ],
736
            'query_cache_array' => [
737
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
738
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_query_cache',
739
                'cacheName' => 'query_cache_driver',
740
                'cacheConfig' => 'array',
741
            ],
742
            'result_cache_array' => [
743
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
744
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_result_cache',
745
                'cacheName' => 'result_cache_driver',
746
                'cacheConfig' => 'array',
747
            ],
748
        ];
749
    }
750
751
    /**
752
     * @param array|string $cacheConfig
753
     *
754
     * @dataProvider cacheConfigurationProvider
755
     */
756 View Code Duplication
    public function testCacheConfiguration(string $expectedAliasName, string $expectedAliasTarget, string $cacheName, $cacheConfig) : void
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...
757
    {
758
        $container = $this->getContainer();
759
        $extension = new DoctrineExtension();
760
761
        $config = BundleConfigurationBuilder::createBuilder()
762
            ->addBaseConnection()
763
            ->addEntityManager([$cacheName => $cacheConfig])
764
            ->build();
765
766
        $extension->load([$config], $container);
767
768
        $this->assertTrue($container->hasAlias($expectedAliasName));
769
        $alias = $container->getAlias($expectedAliasName);
770
        $this->assertEquals($expectedAliasTarget, (string) $alias);
771
    }
772
773
    public static function cacheConfigurationProvider() : array
774
    {
775
        return [
776
            'metadata_cache_default' => [
777
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
778
                'expectedAliasTarget' => 'doctrine.orm.cache.pool.cache.system',
779
                'cacheName' => 'metadata_cache_driver',
780
                'cacheConfig' => ['type' => null],
781
            ],
782
            'query_cache_default' => [
783
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
784
                'expectedAliasTarget' => 'doctrine.orm.cache.pool.cache.app',
785
                'cacheName' => 'query_cache_driver',
786
                'cacheConfig' => ['type' => null],
787
            ],
788
            'result_cache_default' => [
789
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
790
                'expectedAliasTarget' => 'doctrine.orm.cache.pool.cache.app',
791
                'cacheName' => 'result_cache_driver',
792
                'cacheConfig' => ['type' => null],
793
            ],
794
795
            'metadata_cache_pool' => [
796
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
797
                'expectedAliasTarget' => 'doctrine.orm.cache.pool.metadata_cache_pool',
798
                'cacheName' => 'metadata_cache_driver',
799
                'cacheConfig' => ['type' => 'pool', 'pool' => 'metadata_cache_pool'],
800
            ],
801
            'query_cache_pool' => [
802
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
803
                'expectedAliasTarget' => 'doctrine.orm.cache.pool.query_cache_pool',
804
                'cacheName' => 'query_cache_driver',
805
                'cacheConfig' => ['type' => 'pool', 'pool' => 'query_cache_pool'],
806
            ],
807
            'result_cache_pool' => [
808
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
809
                'expectedAliasTarget' => 'doctrine.orm.cache.pool.result_cache_pool',
810
                'cacheName' => 'result_cache_driver',
811
                'cacheConfig' => ['type' => 'pool', 'pool' => 'result_cache_pool'],
812
            ],
813
814
            'metadata_cache_service' => [
815
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
816
                'expectedAliasTarget' => 'service_target_metadata',
817
                'cacheName' => 'metadata_cache_driver',
818
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'],
819
            ],
820
            'query_cache_service' => [
821
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
822
                'expectedAliasTarget' => 'service_target_query',
823
                'cacheName' => 'query_cache_driver',
824
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_query'],
825
            ],
826
            'result_cache_service' => [
827
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
828
                'expectedAliasTarget' => 'service_target_result',
829
                'cacheName' => 'result_cache_driver',
830
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_result'],
831
            ],
832
        ];
833
    }
834
835
    public function testShardManager()
836
    {
837
        $container = $this->getContainer();
838
        $extension = new DoctrineExtension();
839
840
        $config = BundleConfigurationBuilder::createBuilder()
841
             ->addConnection([
842
                 'connections' => [
843
                     'foo' => [
844
                         'shards' => [
845
                             'test' => ['id' => 1],
846
                         ],
847
                     ],
848
                     'bar' => [],
849
                 ],
850
             ])
851
            ->build();
852
853
        $extension->load([$config], $container);
854
855
        $this->assertTrue($container->hasDefinition('doctrine.dbal.foo_shard_manager'));
856
        $this->assertFalse($container->hasDefinition('doctrine.dbal.bar_shard_manager'));
857
    }
858
859
    private function getContainer($bundles = 'YamlBundle', $vendor = null)
860
    {
861
        $bundles = (array) $bundles;
862
863
        $map = [];
864
        foreach ($bundles as $bundle) {
865
            require_once __DIR__ . '/Fixtures/Bundles/' . ($vendor ? $vendor . '/' : '') . $bundle . '/' . $bundle . '.php';
866
867
            $map[$bundle] = 'Fixtures\\Bundles\\' . ($vendor ? $vendor . '\\' : '') . $bundle . '\\' . $bundle;
868
        }
869
870
        $container = new ContainerBuilder(new ParameterBag([
871
            'kernel.name' => 'app',
872
            'kernel.debug' => false,
873
            'kernel.bundles' => $map,
874
            'kernel.cache_dir' => sys_get_temp_dir(),
875
            'kernel.environment' => 'test',
876
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
877
        ]));
878
879
        // Register dummy cache services so we don't have to load the FrameworkExtension
880
        $container->setDefinition('cache.system', (new Definition(ArrayAdapter::class))->setPublic(true));
881
        $container->setDefinition('cache.app', (new Definition(ArrayAdapter::class))->setPublic(true));
882
        $container->setDefinition('my_pool', (new Definition(ArrayAdapter::class))->setPublic(true));
883
884
        return $container;
885
    }
886
887
    private function assertDICConstructorArguments(Definition $definition, array $args)
888
    {
889
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
890
    }
891
892 View Code Duplication
    private function assertDICDefinitionMethodCallAt($pos, Definition $definition, $methodName, array $params = null)
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...
893
    {
894
        $calls = $definition->getMethodCalls();
895
        if (! isset($calls[$pos][0])) {
896
            return;
897
        }
898
899
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
900
901
        if ($params === null) {
902
            return;
903
        }
904
905
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
906
    }
907
908
    /**
909
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
910
     *
911
     * @param string     $methodName
912
     * @param array|null $params
913
     */
914 View Code Duplication
    private function assertDICDefinitionMethodCallOnce(Definition $definition, $methodName, array $params = null)
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...
915
    {
916
        $calls  = $definition->getMethodCalls();
917
        $called = false;
918
        foreach ($calls as $call) {
919
            if ($call[0] !== $methodName) {
920
                continue;
921
            }
922
923
            if ($called) {
924
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
925
            } else {
926
                $called = true;
927
                if ($params !== null) {
928
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
929
                }
930
            }
931
        }
932
        if ($called) {
933
            return;
934
        }
935
936
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
937
    }
938
939
    private function compileContainer(ContainerBuilder $container)
940
    {
941
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
942
        $container->getCompilerPassConfig()->setRemovingPasses([]);
943
        $container->compile();
944
    }
945
}
946
947
class TestWrapperClass extends Connection
948
{
949
}
950