Completed
Pull Request — master (#892)
by Andreas
02:15
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
    public function testCacheConfiguration()
669
    {
670
        $container = $this->getContainer();
671
        $extension = new DoctrineExtension();
672
673
        $config = BundleConfigurationBuilder::createBuilder()
674
             ->addBaseConnection()
675
             ->addEntityManager([
676
                 'metadata_cache_driver' => ['cache_provider' => 'metadata_cache'],
677
                 'query_cache_driver' => ['cache_provider' => 'query_cache'],
678
                 'result_cache_driver' => ['cache_provider' => 'result_cache'],
679
             ])
680
            ->build();
681
682
        $extension->load([$config], $container);
683
684
        $this->assertTrue($container->hasAlias('doctrine.orm.default_metadata_cache'));
685
        $alias = $container->getAlias('doctrine.orm.default_metadata_cache');
686
        $this->assertEquals('doctrine_cache.providers.metadata_cache', (string) $alias);
687
688
        $this->assertTrue($container->hasAlias('doctrine.orm.default_query_cache'));
689
        $alias = $container->getAlias('doctrine.orm.default_query_cache');
690
        $this->assertEquals('doctrine_cache.providers.query_cache', (string) $alias);
691
692
        $this->assertTrue($container->hasAlias('doctrine.orm.default_result_cache'));
693
        $alias = $container->getAlias('doctrine.orm.default_result_cache');
694
        $this->assertEquals('doctrine_cache.providers.result_cache', (string) $alias);
695
    }
696
697
    public function testShardManager()
698
    {
699
        $container = $this->getContainer();
700
        $extension = new DoctrineExtension();
701
702
        $config = BundleConfigurationBuilder::createBuilder()
703
             ->addConnection([
704
                 'connections' => [
705
                     'foo' => [
706
                         'shards' => [
707
                             'test' => ['id' => 1],
708
                         ],
709
                     ],
710
                     'bar' => [],
711
                 ],
712
             ])
713
            ->build();
714
715
        $extension->load([$config], $container);
716
717
        $this->assertTrue($container->hasDefinition('doctrine.dbal.foo_shard_manager'));
718
        $this->assertFalse($container->hasDefinition('doctrine.dbal.bar_shard_manager'));
719
    }
720
721
    private function getContainer($bundles = 'YamlBundle', $vendor = null)
722
    {
723
        $bundles = (array) $bundles;
724
725
        $map = [];
726
        foreach ($bundles as $bundle) {
727
            require_once __DIR__ . '/Fixtures/Bundles/' . ($vendor ? $vendor . '/' : '') . $bundle . '/' . $bundle . '.php';
728
729
            $map[$bundle] = 'Fixtures\\Bundles\\' . ($vendor ? $vendor . '\\' : '') . $bundle . '\\' . $bundle;
730
        }
731
732
        return new ContainerBuilder(new ParameterBag([
733
            'kernel.name' => 'app',
734
            'kernel.debug' => false,
735
            'kernel.bundles' => $map,
736
            'kernel.cache_dir' => sys_get_temp_dir(),
737
            'kernel.environment' => 'test',
738
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
739
        ]));
740
    }
741
742
    private function assertDICConstructorArguments(Definition $definition, array $args)
743
    {
744
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
745
    }
746
747 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...
748
    {
749
        $calls = $definition->getMethodCalls();
750
        if (! isset($calls[$pos][0])) {
751
            return;
752
        }
753
754
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
755
756
        if ($params === null) {
757
            return;
758
        }
759
760
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
761
    }
762
763
    /**
764
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
765
     *
766
     * @param string     $methodName
767
     * @param array|null $params
768
     */
769 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...
770
    {
771
        $calls  = $definition->getMethodCalls();
772
        $called = false;
773
        foreach ($calls as $call) {
774
            if ($call[0] !== $methodName) {
775
                continue;
776
            }
777
778
            if ($called) {
779
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
780
            } else {
781
                $called = true;
782
                if ($params !== null) {
783
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
784
                }
785
            }
786
        }
787
        if ($called) {
788
            return;
789
        }
790
791
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
792
    }
793
794
    private function compileContainer(ContainerBuilder $container)
795
    {
796
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
797
        $container->getCompilerPassConfig()->setRemovingPasses([]);
798
        $container->compile();
799
    }
800
}
801
802
class TestWrapperClass extends Connection
803
{
804
}
805