Completed
Push — master ( eb88c4...8af32b )
by Andreas
02:03
created

DoctrineExtensionTest::testMessengerIntegration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
cc 2
nc 2
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\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Definition;
17
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
18
use Symfony\Component\DependencyInjection\Reference;
19
use Symfony\Component\Messenger\MessageBusInterface;
20
21
class DoctrineExtensionTest extends TestCase
22
{
23
    public function testAutowiringAlias()
24
    {
25
        $container = $this->getContainer();
26
        $extension = new DoctrineExtension();
27
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
28
29
        $extension->load([$config], $container);
30
31
        $expectedAliases = [
32
            DriverConnection::class => 'database_connection',
33
            Connection::class => 'database_connection',
34
            ManagerRegistry::class => 'doctrine',
35
            ObjectManager::class => 'doctrine.orm.entity_manager',
36
            EntityManagerInterface::class => 'doctrine.orm.entity_manager',
37
        ];
38
39
        foreach ($expectedAliases as $id => $target) {
40
            $this->assertTrue($container->hasAlias($id), sprintf('The container should have a `%s` alias for autowiring support.', $id));
41
42
            $alias = $container->getAlias($id);
43
            $this->assertEquals($target, (string) $alias, sprintf('The autowiring for `%s` should use `%s`.', $id, $target));
44
            $this->assertFalse($alias->isPublic(), sprintf('The autowiring alias for `%s` should be private.', $id, $target));
45
        }
46
    }
47
48
    public function testPublicServicesAndAliases()
49
    {
50
        $container = $this->getContainer();
51
        $extension = new DoctrineExtension();
52
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
53
54
        $extension->load([$config], $container);
55
56
        $this->assertTrue($container->getDefinition('doctrine')->isPublic());
57
        $this->assertTrue($container->getAlias('doctrine.orm.entity_manager')->isPublic());
58
        $this->assertTrue($container->getAlias('database_connection')->isPublic());
59
    }
60
61
    public function testDbalGenerateDefaultConnectionConfiguration()
62
    {
63
        $container = $this->getContainer();
64
        $extension = new DoctrineExtension();
65
66
        $container->registerExtension($extension);
67
68
        $extension->load([['dbal' => []]], $container);
69
70
        // doctrine.dbal.default_connection
71
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3));
72
        $this->assertEquals('default', $container->getParameter('doctrine.default_connection'));
73
        $this->assertEquals('root', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['user']);
74
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['password']);
75
        $this->assertEquals('localhost', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['host']);
76
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['port']);
77
        $this->assertEquals('pdo_mysql', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driver']);
78
        $this->assertEquals([], $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driverOptions']);
79
    }
80
81
    public function testDbalOverrideDefaultConnection()
82
    {
83
        $container = $this->getContainer();
84
        $extension = new DoctrineExtension();
85
86
        $container->registerExtension($extension);
87
88
        $extension->load([[], ['dbal' => ['default_connection' => 'foo']], []], $container);
89
90
        // doctrine.dbal.default_connection
91
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3), '->load() overrides existing configuration options');
92
        $this->assertEquals('foo', $container->getParameter('doctrine.default_connection'), '->load() overrides existing configuration options');
93
    }
94
95
    /**
96
     * @expectedException \LogicException
97
     * @expectedExceptionMessage Configuring the ORM layer requires to configure the DBAL layer as well.
98
     */
99
    public function testOrmRequiresDbal()
100
    {
101
        $extension = new DoctrineExtension();
102
103
        $extension->load([['orm' => ['auto_mapping' => true]]], $this->getContainer());
104
    }
105
106
    public function getAutomappingConfigurations()
107
    {
108
        return [
109
            [
110
                [
111
                    'em1' => [
112
                        'mappings' => ['YamlBundle' => null],
113
                    ],
114
                    'em2' => [
115
                        'mappings' => ['XmlBundle' => null],
116
                    ],
117
                ],
118
            ],
119
            [
120
                [
121
                    'em1' => ['auto_mapping' => true],
122
                    'em2' => [
123
                        'mappings' => ['XmlBundle' => null],
124
                    ],
125
                ],
126
            ],
127
            [
128
                [
129
                    'em1' => [
130
                        'auto_mapping' => true,
131
                        'mappings' => ['YamlBundle' => null],
132
                    ],
133
                    'em2' => [
134
                        'mappings' => ['XmlBundle' => null],
135
                    ],
136
                ],
137
            ],
138
        ];
139
    }
140
141
    /**
142
     * @dataProvider getAutomappingConfigurations
143
     */
144
    public function testAutomapping(array $entityManagers)
145
    {
146
        $extension = new DoctrineExtension();
147
148
        $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...
149
            'YamlBundle',
150
            'XmlBundle',
151
        ]);
152
153
        $extension->load(
154
            [
155
                [
156
                    'dbal' => [
157
                        'default_connection' => 'cn1',
158
                        'connections' => [
159
                            'cn1' => [],
160
                            'cn2' => [],
161
                        ],
162
                    ],
163
                    'orm' => ['entity_managers' => $entityManagers],
164
                ],
165
            ],
166
            $container
167
        );
168
169
        $configEm1 = $container->getDefinition('doctrine.orm.em1_configuration');
170
        $configEm2 = $container->getDefinition('doctrine.orm.em2_configuration');
171
172
        $this->assertContains(
173
            [
174
                'setEntityNamespaces',
175
                [
176
                    ['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'],
177
                ],
178
            ],
179
            $configEm1->getMethodCalls()
180
        );
181
182
        $this->assertContains(
183
            [
184
                'setEntityNamespaces',
185
                [
186
                    ['XmlBundle' => 'Fixtures\Bundles\XmlBundle\Entity'],
187
                ],
188
            ],
189
            $configEm2->getMethodCalls()
190
        );
191
    }
192
193
    public function testDbalLoad()
194
    {
195
        $container = $this->getContainer();
196
        $extension = new DoctrineExtension();
197
198
        $extension->load([
199
            ['dbal' => ['connections' => ['default' => ['password' => 'foo']]]],
200
            [],
201
            ['dbal' => ['default_connection' => 'foo']],
202
            [],
203
        ], $container);
204
205
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
206
207
        $this->assertEquals('foo', $config['password']);
208
        $this->assertEquals('root', $config['user']);
209
    }
210
211
    public function testDbalWrapperClass()
212
    {
213
        $container = $this->getContainer();
214
        $extension = new DoctrineExtension();
215
216
        $extension->load(
217
            [
218
                [
219
                    'dbal' => [
220
                        'connections' => [
221
                            'default' => ['password' => 'foo', 'wrapper_class' => TestWrapperClass::class],
222
                            'second' => ['password' => 'boo'],
223
                        ],
224
                    ],
225
                ],
226
                [],
227
                ['dbal' => ['default_connection' => 'foo']],
228
                [],
229
            ],
230
            $container
231
        );
232
233
        $this->assertEquals(TestWrapperClass::class, $container->getDefinition('doctrine.dbal.default_connection')->getClass());
234
        $this->assertNull($container->getDefinition('doctrine.dbal.second_connection')->getClass());
235
    }
236
237
    public function testDependencyInjectionConfigurationDefaults()
238
    {
239
        $container = $this->getContainer();
240
        $extension = new DoctrineExtension();
241
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
242
243
        $extension->load([$config], $container);
244
245
        $this->assertFalse($container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
246
        $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration.class'));
247
        $this->assertEquals('Doctrine\ORM\EntityManager', $container->getParameter('doctrine.orm.entity_manager.class'));
248
        $this->assertEquals('Proxies', $container->getParameter('doctrine.orm.proxy_namespace'));
249
        $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.orm.cache.array.class'));
250
        $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.orm.cache.apc.class'));
251
        $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.orm.cache.memcache.class'));
252
        $this->assertEquals('localhost', $container->getParameter('doctrine.orm.cache.memcache_host'));
253
        $this->assertEquals('11211', $container->getParameter('doctrine.orm.cache.memcache_port'));
254
        $this->assertEquals('Memcache', $container->getParameter('doctrine.orm.cache.memcache_instance.class'));
255
        $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.orm.cache.xcache.class'));
256
        $this->assertEquals('Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class'));
257
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.orm.metadata.annotation.class'));
258
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver', $container->getParameter('doctrine.orm.metadata.xml.class'));
259
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver', $container->getParameter('doctrine.orm.metadata.yml.class'));
260
261
        // second-level cache
262
        $this->assertEquals('Doctrine\ORM\Cache\DefaultCacheFactory', $container->getParameter('doctrine.orm.second_level_cache.default_cache_factory.class'));
263
        $this->assertEquals('Doctrine\ORM\Cache\Region\DefaultRegion', $container->getParameter('doctrine.orm.second_level_cache.default_region.class'));
264
        $this->assertEquals('Doctrine\ORM\Cache\Region\FileLockRegion', $container->getParameter('doctrine.orm.second_level_cache.filelock_region.class'));
265
        $this->assertEquals('Doctrine\ORM\Cache\Logging\CacheLoggerChain', $container->getParameter('doctrine.orm.second_level_cache.logger_chain.class'));
266
        $this->assertEquals('Doctrine\ORM\Cache\Logging\StatisticsCacheLogger', $container->getParameter('doctrine.orm.second_level_cache.logger_statistics.class'));
267
        $this->assertEquals('Doctrine\ORM\Cache\CacheConfiguration', $container->getParameter('doctrine.orm.second_level_cache.cache_configuration.class'));
268
        $this->assertEquals('Doctrine\ORM\Cache\RegionsConfiguration', $container->getParameter('doctrine.orm.second_level_cache.regions_configuration.class'));
269
270
        $config = BundleConfigurationBuilder::createBuilder()
271
            ->addBaseConnection()
272
            ->addEntityManager([
273
                'proxy_namespace' => 'MyProxies',
274
                'auto_generate_proxy_classes' => true,
275
                'default_entity_manager' => 'default',
276
                'entity_managers' => [
277
                    'default' => [
278
                        'mappings' => ['YamlBundle' => []],
279
                    ],
280
                ],
281
            ])
282
            ->build();
283
284
        $container = $this->getContainer();
285
        $extension->load([$config], $container);
286
        $this->compileContainer($container);
287
288
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
289
290
        $args = $definition->getArguments();
291
        $this->assertEquals('pdo_mysql', $args[0]['driver']);
292
        $this->assertEquals('localhost', $args[0]['host']);
293
        $this->assertEquals('root', $args[0]['user']);
294
        $this->assertEquals('doctrine.dbal.default_connection.configuration', (string) $args[1]);
295
        $this->assertEquals('doctrine.dbal.default_connection.event_manager', (string) $args[2]);
296
        $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...
297
298
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
299
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
300
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
301
302
        $this->assertEquals(['default' => 'doctrine.orm.default_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
303
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
304
305
        $arguments = $definition->getArguments();
306
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
307
        $this->assertEquals('doctrine.dbal.default_connection', (string) $arguments[0]);
308
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
309
        $this->assertEquals('doctrine.orm.default_configuration', (string) $arguments[1]);
310
311
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
312
        $calls      = array_values($definition->getMethodCalls());
313
        $this->assertEquals(['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'], $calls[0][1][0]);
314
        $this->assertEquals('doctrine.orm.default_metadata_cache', (string) $calls[1][1][0]);
315
        $this->assertEquals('doctrine.orm.default_query_cache', (string) $calls[2][1][0]);
316
        $this->assertEquals('doctrine.orm.default_result_cache', (string) $calls[3][1][0]);
317
318
        $this->assertEquals('doctrine.orm.naming_strategy.default', (string) $calls[10][1][0]);
319
        $this->assertEquals('doctrine.orm.quote_strategy.default', (string) $calls[11][1][0]);
320
        $this->assertEquals('doctrine.orm.default_entity_listener_resolver', (string) $calls[12][1][0]);
321
322
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
323
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
324
325
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_query_cache'));
326
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
327
328
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_result_cache'));
329
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
330
    }
331
332
    public function testUseSavePointsAddMethodCallToAddSavepointsToTheConnection()
333
    {
334
        $container = $this->getContainer();
335
        $extension = new DoctrineExtension();
336
337
        $extension->load([[
338
            'dbal' => [
339
                'connections' => [
340
                    'default' => ['password' => 'foo', 'use_savepoints' => true],
341
                ],
342
            ],
343
        ],
344
        ], $container);
345
346
        $calls = $container->getDefinition('doctrine.dbal.default_connection')->getMethodCalls();
347
        $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...
348
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
349
        $this->assertTrue($calls[0][1][0]);
350
    }
351
352
    public function testAutoGenerateProxyClasses()
353
    {
354
        $container = $this->getContainer();
355
        $extension = new DoctrineExtension();
356
357
        $config = BundleConfigurationBuilder::createBuilder()
358
            ->addBaseConnection()
359
            ->addEntityManager([
360
                'proxy_namespace' => 'MyProxies',
361
                'auto_generate_proxy_classes' => 'eval',
362
                'default_entity_manager' => 'default',
363
                'entity_managers' => [
364
                    'default' => [
365
                        'mappings' => ['YamlBundle' => []],
366
                    ],
367
                ],
368
            ])
369
            ->build();
370
371
        $extension->load([$config], $container);
372
373
        $this->assertEquals(AbstractProxyFactory::AUTOGENERATE_EVAL, $container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
374
    }
375
376
    public function testSingleEntityManagerWithDefaultConfiguration()
377
    {
378
        $container = $this->getContainer();
379
        $extension = new DoctrineExtension();
380
381
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
382
383
        $extension->load([$configurationArray], $container);
384
        $this->compileContainer($container);
385
386
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
387
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
388
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
389
390
        $this->assertDICConstructorArguments($definition, [
391
            new Reference('doctrine.dbal.default_connection'),
392
            new Reference('doctrine.orm.default_configuration'),
393
        ]);
394
    }
395
396
    public function testSingleEntityManagerWithDefaultSecondLevelCacheConfiguration()
397
    {
398
        $container = $this->getContainer();
399
        $extension = new DoctrineExtension();
400
401
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
402
            ->addBaseSecondLevelCache()
403
            ->build();
404
405
        $extension->load([$configurationArray], $container);
406
        $this->compileContainer($container);
407
408
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
409
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
410
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
411
412
        $this->assertDICConstructorArguments($definition, [
413
            new Reference('doctrine.dbal.default_connection'),
414
            new Reference('doctrine.orm.default_configuration'),
415
        ]);
416
417
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
418
        $this->assertEquals('%doctrine.orm.second_level_cache.default_cache_factory.class%', $slcDefinition->getClass());
419
    }
420
421
    public function testSingleEntityManagerWithCustomSecondLevelCacheConfiguration()
422
    {
423
        $container = $this->getContainer();
424
        $extension = new DoctrineExtension();
425
426
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
427
            ->addSecondLevelCache([
428
                'region_cache_driver' => ['type' => 'memcache'],
429
                'regions' => [
430
                    'hour_region' => ['lifetime' => 3600],
431
                ],
432
                'factory' => 'YamlBundle\Cache\MyCacheFactory',
433
            ])
434
            ->build();
435
436
        $extension->load([$configurationArray], $container);
437
        $this->compileContainer($container);
438
439
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
440
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
441
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
442
443
        $this->assertDICConstructorArguments($definition, [
444
            new Reference('doctrine.dbal.default_connection'),
445
            new Reference('doctrine.orm.default_configuration'),
446
        ]);
447
448
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
449
        $this->assertEquals('YamlBundle\Cache\MyCacheFactory', $slcDefinition->getClass());
450
    }
451
452 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...
453
    {
454
        $container = $this->getContainer();
455
        $extension = new DoctrineExtension();
456
457
        $config        = BundleConfigurationBuilder::createBuilder()
458
             ->addBaseConnection()
459
             ->build();
460
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => []]]]];
461
        $extension->load([$config], $container);
462
463
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
464
        $this->assertDICDefinitionMethodCallOnce(
465
            $definition,
466
            'setEntityNamespaces',
467
            [['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity']]
468
        );
469
    }
470
471 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...
472
    {
473
        $container = $this->getContainer();
474
        $extension = new DoctrineExtension();
475
476
        $config        = BundleConfigurationBuilder::createBuilder()
477
             ->addBaseConnection()
478
             ->build();
479
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => ['alias' => 'yml']]]]];
480
        $extension->load([$config], $container);
481
482
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
483
        $this->assertDICDefinitionMethodCallOnce(
484
            $definition,
485
            'setEntityNamespaces',
486
            [['yml' => 'Fixtures\Bundles\YamlBundle\Entity']]
487
        );
488
    }
489
490
    public function testYamlBundleMappingDetection()
491
    {
492
        $container = $this->getContainer('YamlBundle');
493
        $extension = new DoctrineExtension();
494
495
        $config = BundleConfigurationBuilder::createBuilder()
496
            ->addBaseConnection()
497
            ->addBaseEntityManager()
498
            ->build();
499
        $extension->load([$config], $container);
500
501
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
502
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
503
            new Reference('doctrine.orm.default_yml_metadata_driver'),
504
            'Fixtures\Bundles\YamlBundle\Entity',
505
        ]);
506
    }
507
508 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...
509
    {
510
        $container = $this->getContainer('XmlBundle');
511
        $extension = new DoctrineExtension();
512
513
        $config = BundleConfigurationBuilder::createBuilder()
514
            ->addBaseConnection()
515
            ->addEntityManager([
516
                'default_entity_manager' => 'default',
517
                'entity_managers' => [
518
                    'default' => [
519
                        'mappings' => [
520
                            'XmlBundle' => [],
521
                        ],
522
                    ],
523
                ],
524
            ])
525
            ->build();
526
        $extension->load([$config], $container);
527
528
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
529
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
530
            new Reference('doctrine.orm.default_xml_metadata_driver'),
531
            'Fixtures\Bundles\XmlBundle\Entity',
532
        ]);
533
    }
534
535 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...
536
    {
537
        $container = $this->getContainer('AnnotationsBundle');
538
        $extension = new DoctrineExtension();
539
540
        $config = BundleConfigurationBuilder::createBuilder()
541
            ->addBaseConnection()
542
            ->addEntityManager([
543
                'default_entity_manager' => 'default',
544
                'entity_managers' => [
545
                    'default' => [
546
                        'mappings' => [
547
                            'AnnotationsBundle' => [],
548
                        ],
549
                    ],
550
                ],
551
            ])
552
            ->build();
553
        $extension->load([$config], $container);
554
555
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
556
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
557
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
558
            'Fixtures\Bundles\AnnotationsBundle\Entity',
559
        ]);
560
    }
561
562
    public function testOrmMergeConfigs()
563
    {
564
        $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...
565
        $extension = new DoctrineExtension();
566
567
        $config1 = BundleConfigurationBuilder::createBuilder()
568
            ->addBaseConnection()
569
            ->addEntityManager([
570
                'auto_generate_proxy_classes' => true,
571
                'default_entity_manager' => 'default',
572
                'entity_managers' => [
573
                    'default' => [
574
                        'mappings' => [
575
                            'AnnotationsBundle' => [],
576
                        ],
577
                    ],
578
                ],
579
            ])
580
            ->build();
581
        $config2 = BundleConfigurationBuilder::createBuilder()
582
            ->addBaseConnection()
583
            ->addEntityManager([
584
                'auto_generate_proxy_classes' => false,
585
                'default_entity_manager' => 'default',
586
                'entity_managers' => [
587
                    'default' => [
588
                        'mappings' => [
589
                            'XmlBundle' => [],
590
                        ],
591
                    ],
592
                ],
593
            ])
594
            ->build();
595
        $extension->load([$config1, $config2], $container);
596
597
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
598
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
599
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
600
            'Fixtures\Bundles\AnnotationsBundle\Entity',
601
        ]);
602
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
603
            new Reference('doctrine.orm.default_xml_metadata_driver'),
604
            'Fixtures\Bundles\XmlBundle\Entity',
605
        ]);
606
607
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
608
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setAutoGenerateProxyClasses');
609
610
        $calls = $configDef->getMethodCalls();
611
        foreach ($calls as $call) {
612
            if ($call[0] === 'setAutoGenerateProxyClasses') {
613
                $this->assertFalse($container->getParameterBag()->resolveValue($call[1][0]));
614
                break;
615
            }
616
        }
617
    }
618
619
    public function testAnnotationsBundleMappingDetectionWithVendorNamespace()
620
    {
621
        $container = $this->getContainer('AnnotationsBundle', 'Vendor');
622
        $extension = new DoctrineExtension();
623
624
        $config = BundleConfigurationBuilder::createBuilder()
625
            ->addBaseConnection()
626
            ->addEntityManager([
627
                'default_entity_manager' => 'default',
628
                'entity_managers' => [
629
                    'default' => [
630
                        'mappings' => [
631
                            'AnnotationsBundle' => [],
632
                        ],
633
                    ],
634
                ],
635
            ])
636
            ->build();
637
        $extension->load([$config], $container);
638
639
        $calls = $container->getDefinition('doctrine.orm.default_metadata_driver')->getMethodCalls();
640
        $this->assertEquals('doctrine.orm.default_annotation_metadata_driver', (string) $calls[0][1][0]);
641
        $this->assertEquals('Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]);
642
    }
643
644
    public function testMessengerIntegration()
645
    {
646
        if (! interface_exists(MessageBusInterface::class)) {
647
            $this->markTestSkipped('Symfony Messenger component is not installed');
648
        }
649
650
        $container = $this->getContainer();
651
        $extension = new DoctrineExtension();
652
653
        $config = BundleConfigurationBuilder::createBuilder()
654
            ->addBaseConnection()
655
            ->addEntityManager([
656
                'default_entity_manager' => 'default',
657
                'entity_managers' => [
658
                    'default' => [],
659
                ],
660
            ])
661
            ->build();
662
        $extension->load([$config], $container);
663
664
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_transaction'));
665
        $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...
666
    }
667
668
    /**
669
     * @param array|string $cacheConfig
670
     *
671
     * @dataProvider cacheConfigurationProvider
672
     */
673
    public function testCacheConfiguration(string $expectedAliasName, string $expectedAliasTarget, string $cacheName, $cacheConfig) : void
674
    {
675
        $container = $this->getContainer();
676
        $extension = new DoctrineExtension();
677
678
        $config = BundleConfigurationBuilder::createBuilder()
679
            ->addBaseConnection()
680
            ->addEntityManager([$cacheName => $cacheConfig])
681
            ->build();
682
683
        $extension->load([$config], $container);
684
685
        $this->assertTrue($container->hasAlias($expectedAliasName));
686
        $alias = $container->getAlias($expectedAliasName);
687
        $this->assertEquals($expectedAliasTarget, (string) $alias);
688
    }
689
690
    public static function cacheConfigurationProvider() : array
691
    {
692
        return [
693
            'metadata_cache_provider' => [
694
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
695
                'expectedAliasTarget' => 'doctrine_cache.providers.metadata_cache',
696
                'cacheName' => 'metadata_cache_driver',
697
                'cacheConfig' => ['cache_provider' => 'metadata_cache'],
698
            ],
699
            'query_cache_provider' => [
700
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
701
                'expectedAliasTarget' => 'doctrine_cache.providers.query_cache',
702
                'cacheName' => 'query_cache_driver',
703
                'cacheConfig' => ['cache_provider' => 'query_cache'],
704
            ],
705
            'result_cache_provider' => [
706
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
707
                'expectedAliasTarget' => 'doctrine_cache.providers.result_cache',
708
                'cacheName' => 'result_cache_driver',
709
                'cacheConfig' => ['cache_provider' => 'result_cache'],
710
            ],
711
712
            'metadata_cache_service' => [
713
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
714
                'expectedAliasTarget' => 'service_target_metadata',
715
                'cacheName' => 'metadata_cache_driver',
716
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'],
717
            ],
718
            'query_cache_service' => [
719
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
720
                'expectedAliasTarget' => 'service_target_query',
721
                'cacheName' => 'query_cache_driver',
722
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_query'],
723
            ],
724
            'result_cache_service' => [
725
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
726
                'expectedAliasTarget' => 'service_target_result',
727
                'cacheName' => 'result_cache_driver',
728
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_result'],
729
            ],
730
731
            'metadata_cache_array' => [
732
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
733
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_metadata_cache',
734
                'cacheName' => 'metadata_cache_driver',
735
                'cacheConfig' => 'array',
736
            ],
737
            'query_cache_array' => [
738
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
739
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_query_cache',
740
                'cacheName' => 'query_cache_driver',
741
                'cacheConfig' => 'array',
742
            ],
743
            'result_cache_array' => [
744
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
745
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_result_cache',
746
                'cacheName' => 'result_cache_driver',
747
                'cacheConfig' => 'array',
748
            ],
749
        ];
750
    }
751
752
    public function testShardManager()
753
    {
754
        $container = $this->getContainer();
755
        $extension = new DoctrineExtension();
756
757
        $config = BundleConfigurationBuilder::createBuilder()
758
             ->addConnection([
759
                 'connections' => [
760
                     'foo' => [
761
                         'shards' => [
762
                             'test' => ['id' => 1],
763
                         ],
764
                     ],
765
                     'bar' => [],
766
                 ],
767
             ])
768
            ->build();
769
770
        $extension->load([$config], $container);
771
772
        $this->assertTrue($container->hasDefinition('doctrine.dbal.foo_shard_manager'));
773
        $this->assertFalse($container->hasDefinition('doctrine.dbal.bar_shard_manager'));
774
    }
775
776
    private function getContainer($bundles = 'YamlBundle', $vendor = null)
777
    {
778
        $bundles = (array) $bundles;
779
780
        $map = [];
781
        foreach ($bundles as $bundle) {
782
            require_once __DIR__ . '/Fixtures/Bundles/' . ($vendor ? $vendor . '/' : '') . $bundle . '/' . $bundle . '.php';
783
784
            $map[$bundle] = 'Fixtures\\Bundles\\' . ($vendor ? $vendor . '\\' : '') . $bundle . '\\' . $bundle;
785
        }
786
787
        return new ContainerBuilder(new ParameterBag([
788
            'kernel.name' => 'app',
789
            'kernel.debug' => false,
790
            'kernel.bundles' => $map,
791
            'kernel.cache_dir' => sys_get_temp_dir(),
792
            'kernel.environment' => 'test',
793
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
794
        ]));
795
    }
796
797
    private function assertDICConstructorArguments(Definition $definition, array $args)
798
    {
799
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
800
    }
801
802 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...
803
    {
804
        $calls = $definition->getMethodCalls();
805
        if (! isset($calls[$pos][0])) {
806
            return;
807
        }
808
809
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
810
811
        if ($params === null) {
812
            return;
813
        }
814
815
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
816
    }
817
818
    /**
819
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
820
     *
821
     * @param string     $methodName
822
     * @param array|null $params
823
     */
824 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...
825
    {
826
        $calls  = $definition->getMethodCalls();
827
        $called = false;
828
        foreach ($calls as $call) {
829
            if ($call[0] !== $methodName) {
830
                continue;
831
            }
832
833
            if ($called) {
834
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
835
            } else {
836
                $called = true;
837
                if ($params !== null) {
838
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
839
                }
840
            }
841
        }
842
        if ($called) {
843
            return;
844
        }
845
846
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
847
    }
848
849
    private function compileContainer(ContainerBuilder $container)
850
    {
851
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
852
        $container->getCompilerPassConfig()->setRemovingPasses([]);
853
        $container->compile();
854
    }
855
}
856
857
class TestWrapperClass extends Connection
858
{
859
}
860