Completed
Pull Request — master (#817)
by Maxime
02:41
created

DoctrineExtensionTest::testMessengerIntegration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 20
rs 9.4285
cc 1
eloc 14
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 Doctrine\ORM\Version;
14
use PHPUnit\Framework\TestCase;
15
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
16
use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass;
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
22
class DoctrineExtensionTest extends TestCase
23
{
24
    public function testAutowiringAlias()
25
    {
26
        $container = $this->getContainer();
27
        $extension = new DoctrineExtension();
28
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
29
30
        $extension->load([$config], $container);
31
32
        $expectedAliases = [
33
            DriverConnection::class => 'database_connection',
34
            Connection::class => 'database_connection',
35
            ManagerRegistry::class => 'doctrine',
36
            ObjectManager::class => 'doctrine.orm.entity_manager',
37
            EntityManagerInterface::class => 'doctrine.orm.entity_manager',
38
        ];
39
40
        foreach ($expectedAliases as $id => $target) {
41
            $this->assertTrue($container->hasAlias($id), sprintf('The container should have a `%s` alias for autowiring support.', $id));
42
43
            $alias = $container->getAlias($id);
44
            $this->assertEquals($target, (string) $alias, sprintf('The autowiring for `%s` should use `%s`.', $id, $target));
45
            $this->assertFalse($alias->isPublic(), sprintf('The autowiring alias for `%s` should be private.', $id, $target));
46
        }
47
    }
48
49
    public function testPublicServicesAndAliases()
50
    {
51
        $container = $this->getContainer();
52
        $extension = new DoctrineExtension();
53
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
54
55
        $extension->load([$config], $container);
56
57
        $this->assertTrue($container->getDefinition('doctrine')->isPublic());
58
        $this->assertTrue($container->getAlias('doctrine.orm.entity_manager')->isPublic());
59
        $this->assertTrue($container->getAlias('database_connection')->isPublic());
60
    }
61
62
    public function testDbalGenerateDefaultConnectionConfiguration()
63
    {
64
        $container = $this->getContainer();
65
        $extension = new DoctrineExtension();
66
67
        $container->registerExtension($extension);
68
69
        $extension->load([['dbal' => []]], $container);
70
71
        // doctrine.dbal.default_connection
72
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3));
73
        $this->assertEquals('default', $container->getParameter('doctrine.default_connection'));
74
        $this->assertEquals('root', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['user']);
75
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['password']);
76
        $this->assertEquals('localhost', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['host']);
77
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['port']);
78
        $this->assertEquals('pdo_mysql', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driver']);
79
        $this->assertEquals([], $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driverOptions']);
80
    }
81
82
    public function testDbalOverrideDefaultConnection()
83
    {
84
        $container = $this->getContainer();
85
        $extension = new DoctrineExtension();
86
87
        $container->registerExtension($extension);
88
89
        $extension->load([[], ['dbal' => ['default_connection' => 'foo']], []], $container);
90
91
        // doctrine.dbal.default_connection
92
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3), '->load() overrides existing configuration options');
93
        $this->assertEquals('foo', $container->getParameter('doctrine.default_connection'), '->load() overrides existing configuration options');
94
    }
95
96
    /**
97
     * @expectedException \LogicException
98
     * @expectedExceptionMessage Configuring the ORM layer requires to configure the DBAL layer as well.
99
     */
100
    public function testOrmRequiresDbal()
101
    {
102
        $extension = new DoctrineExtension();
103
104
        $extension->load([['orm' => ['auto_mapping' => true]]], $this->getContainer());
105
    }
106
107
    public function getAutomappingConfigurations()
108
    {
109
        return [
110
            [
111
                [
112
                    'em1' => [
113
                        'mappings' => ['YamlBundle' => null],
114
                    ],
115
                    'em2' => [
116
                        'mappings' => ['XmlBundle' => null],
117
                    ],
118
                ],
119
            ],
120
            [
121
                [
122
                    'em1' => ['auto_mapping' => true],
123
                    'em2' => [
124
                        'mappings' => ['XmlBundle' => null],
125
                    ],
126
                ],
127
            ],
128
            [
129
                [
130
                    'em1' => [
131
                        'auto_mapping' => true,
132
                        'mappings' => ['YamlBundle' => null],
133
                    ],
134
                    'em2' => [
135
                        'mappings' => ['XmlBundle' => null],
136
                    ],
137
                ],
138
            ],
139
        ];
140
    }
141
142
    /**
143
     * @dataProvider getAutomappingConfigurations
144
     */
145
    public function testAutomapping(array $entityManagers)
146
    {
147
        $extension = new DoctrineExtension();
148
149
        if (! method_exists($extension, 'fixManagersAutoMappings')) {
150
            $this->markTestSkipped('Auto mapping with multiple managers available with Symfony ~2.6');
151
        }
152
153
        $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...
154
            'YamlBundle',
155
            'XmlBundle',
156
        ]);
157
158
        $extension->load(
159
            [
160
                [
161
                    'dbal' => [
162
                        'default_connection' => 'cn1',
163
                        'connections' => [
164
                            'cn1' => [],
165
                            'cn2' => [],
166
                        ],
167
                    ],
168
                    'orm' => ['entity_managers' => $entityManagers],
169
                ],
170
            ],
171
            $container
172
        );
173
174
        $configEm1 = $container->getDefinition('doctrine.orm.em1_configuration');
175
        $configEm2 = $container->getDefinition('doctrine.orm.em2_configuration');
176
177
        $this->assertContains(
178
            [
179
                'setEntityNamespaces',
180
                [
181
                    ['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'],
182
                ],
183
            ],
184
            $configEm1->getMethodCalls()
185
        );
186
187
        $this->assertContains(
188
            [
189
                'setEntityNamespaces',
190
                [
191
                    ['XmlBundle' => 'Fixtures\Bundles\XmlBundle\Entity'],
192
                ],
193
            ],
194
            $configEm2->getMethodCalls()
195
        );
196
    }
197
198
    public function testDbalLoad()
199
    {
200
        $container = $this->getContainer();
201
        $extension = new DoctrineExtension();
202
203
        $extension->load([
204
            ['dbal' => ['connections' => ['default' => ['password' => 'foo']]]],
205
            [],
206
            ['dbal' => ['default_connection' => 'foo']],
207
            [],
208
        ], $container);
209
210
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
211
212
        $this->assertEquals('foo', $config['password']);
213
        $this->assertEquals('root', $config['user']);
214
    }
215
216
    public function testDbalWrapperClass()
217
    {
218
        $container = $this->getContainer();
219
        $extension = new DoctrineExtension();
220
221
        $extension->load(
222
            [
223
                [
224
            'dbal' => [
225
            'connections' => [
226
                    'default' => ['password' => 'foo', 'wrapper_class' => TestWrapperClass::class],
227
                    'second' => ['password' => 'boo'],
228
                ],
229
            ],
230
                ],
231
                [],
232
                ['dbal' => ['default_connection' => 'foo']],
233
                [],
234
            ],
235
            $container
236
        );
237
238
        $this->assertEquals(TestWrapperClass::class, $container->getDefinition('doctrine.dbal.default_connection')->getClass());
239
        $this->assertNull($container->getDefinition('doctrine.dbal.second_connection')->getClass());
240
    }
241
242
    public function testDependencyInjectionConfigurationDefaults()
243
    {
244
        $container = $this->getContainer();
245
        $extension = new DoctrineExtension();
246
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
247
248
        $extension->load([$config], $container);
249
250
        $this->assertFalse($container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
251
        $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration.class'));
252
        $this->assertEquals('Doctrine\ORM\EntityManager', $container->getParameter('doctrine.orm.entity_manager.class'));
253
        $this->assertEquals('Proxies', $container->getParameter('doctrine.orm.proxy_namespace'));
254
        $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.orm.cache.array.class'));
255
        $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.orm.cache.apc.class'));
256
        $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.orm.cache.memcache.class'));
257
        $this->assertEquals('localhost', $container->getParameter('doctrine.orm.cache.memcache_host'));
258
        $this->assertEquals('11211', $container->getParameter('doctrine.orm.cache.memcache_port'));
259
        $this->assertEquals('Memcache', $container->getParameter('doctrine.orm.cache.memcache_instance.class'));
260
        $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.orm.cache.xcache.class'));
261
        $this->assertEquals('Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class'));
262
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.orm.metadata.annotation.class'));
263
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver', $container->getParameter('doctrine.orm.metadata.xml.class'));
264
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver', $container->getParameter('doctrine.orm.metadata.yml.class'));
265
266
        // second-level cache
267
        $this->assertEquals('Doctrine\ORM\Cache\DefaultCacheFactory', $container->getParameter('doctrine.orm.second_level_cache.default_cache_factory.class'));
268
        $this->assertEquals('Doctrine\ORM\Cache\Region\DefaultRegion', $container->getParameter('doctrine.orm.second_level_cache.default_region.class'));
269
        $this->assertEquals('Doctrine\ORM\Cache\Region\FileLockRegion', $container->getParameter('doctrine.orm.second_level_cache.filelock_region.class'));
270
        $this->assertEquals('Doctrine\ORM\Cache\Logging\CacheLoggerChain', $container->getParameter('doctrine.orm.second_level_cache.logger_chain.class'));
271
        $this->assertEquals('Doctrine\ORM\Cache\Logging\StatisticsCacheLogger', $container->getParameter('doctrine.orm.second_level_cache.logger_statistics.class'));
272
        $this->assertEquals('Doctrine\ORM\Cache\CacheConfiguration', $container->getParameter('doctrine.orm.second_level_cache.cache_configuration.class'));
273
        $this->assertEquals('Doctrine\ORM\Cache\RegionsConfiguration', $container->getParameter('doctrine.orm.second_level_cache.regions_configuration.class'));
274
275
        $config = BundleConfigurationBuilder::createBuilder()
276
            ->addBaseConnection()
277
            ->addEntityManager([
278
                'proxy_namespace' => 'MyProxies',
279
                'auto_generate_proxy_classes' => true,
280
                'default_entity_manager' => 'default',
281
                'entity_managers' => [
282
                    'default' => [
283
                        'mappings' => ['YamlBundle' => []],
284
                    ],
285
                ],
286
            ])
287
            ->build();
288
289
        $container = $this->getContainer();
290
        $extension->load([$config], $container);
291
        $this->compileContainer($container);
292
293
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
294
295
        $args = $definition->getArguments();
296
        $this->assertEquals('pdo_mysql', $args[0]['driver']);
297
        $this->assertEquals('localhost', $args[0]['host']);
298
        $this->assertEquals('root', $args[0]['user']);
299
        $this->assertEquals('doctrine.dbal.default_connection.configuration', (string) $args[1]);
300
        $this->assertEquals('doctrine.dbal.default_connection.event_manager', (string) $args[2]);
301
        $this->assertCount(0, $definition->getMethodCalls());
302
303
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
304
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
305 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
306
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
307
        } else {
308
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
309
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
310
        }
311
312
        $this->assertEquals(['default' => 'doctrine.orm.default_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
313
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
314
315
        $arguments = $definition->getArguments();
316
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
317
        $this->assertEquals('doctrine.dbal.default_connection', (string) $arguments[0]);
318
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
319
        $this->assertEquals('doctrine.orm.default_configuration', (string) $arguments[1]);
320
321
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
322
        $calls      = array_values($definition->getMethodCalls());
323
        $this->assertEquals(['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'], $calls[0][1][0]);
324
        $this->assertEquals('doctrine.orm.default_metadata_cache', (string) $calls[1][1][0]);
325
        $this->assertEquals('doctrine.orm.default_query_cache', (string) $calls[2][1][0]);
326
        $this->assertEquals('doctrine.orm.default_result_cache', (string) $calls[3][1][0]);
327
328
        if (version_compare(Version::VERSION, '2.3.0-DEV') >= 0) {
329
            $this->assertEquals('doctrine.orm.naming_strategy.default', (string) $calls[10][1][0]);
330
            $this->assertEquals('doctrine.orm.quote_strategy.default', (string) $calls[11][1][0]);
331
        }
332
        if (version_compare(Version::VERSION, '2.4.0-DEV') >= 0) {
333
            $this->assertEquals('doctrine.orm.default_entity_listener_resolver', (string) $calls[12][1][0]);
334
        }
335
336
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
337
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
338
339
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_query_cache'));
340
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
341
342
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_result_cache'));
343
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
344
    }
345
346
    public function testUseSavePointsAddMethodCallToAddSavepointsToTheConnection()
347
    {
348
        $container = $this->getContainer();
349
        $extension = new DoctrineExtension();
350
351
        $extension->load([[
352
        'dbal' => [
353
        'connections' => [
354
            'default' => ['password' => 'foo', 'use_savepoints' => true],
355
        ],
356
        ],
357
        ],
358
        ], $container);
359
360
        $calls = $container->getDefinition('doctrine.dbal.default_connection')->getMethodCalls();
361
        $this->assertCount(1, $calls);
362
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
363
        $this->assertTrue($calls[0][1][0]);
364
    }
365
366
    public function testAutoGenerateProxyClasses()
367
    {
368
        $container = $this->getContainer();
369
        $extension = new DoctrineExtension();
370
371
        $config = BundleConfigurationBuilder::createBuilder()
372
            ->addBaseConnection()
373
            ->addEntityManager([
374
                'proxy_namespace' => 'MyProxies',
375
                'auto_generate_proxy_classes' => 'eval',
376
                'default_entity_manager' => 'default',
377
                'entity_managers' => [
378
                    'default' => [
379
                        'mappings' => ['YamlBundle' => []],
380
                    ],
381
                ],
382
            ])
383
            ->build();
384
385
        $extension->load([$config], $container);
386
387
        $this->assertEquals(AbstractProxyFactory::AUTOGENERATE_EVAL, $container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
388
    }
389
390
    public function testSingleEntityManagerWithDefaultConfiguration()
391
    {
392
        $container = $this->getContainer();
393
        $extension = new DoctrineExtension();
394
395
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
396
397
        $extension->load([$configurationArray], $container);
398
        $this->compileContainer($container);
399
400
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
401
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
402 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
403
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
404
        } else {
405
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
406
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
407
        }
408
409
        $this->assertDICConstructorArguments($definition, [
410
            new Reference('doctrine.dbal.default_connection'),
411
        new Reference('doctrine.orm.default_configuration'),
412
        ]);
413
    }
414
415
    public function testSingleEntityManagerWithDefaultSecondLevelCacheConfiguration()
416
    {
417
        if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) {
418
            $this->markTestSkipped(sprintf('Second Level cache not supported by this version of the ORM : %s', Version::VERSION));
419
        }
420
        $container = $this->getContainer();
421
        $extension = new DoctrineExtension();
422
423
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
424
            ->addBaseSecondLevelCache()
425
            ->build();
426
427
        $extension->load([$configurationArray], $container);
428
        $this->compileContainer($container);
429
430
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
431
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
432 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
433
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
434
        } else {
435
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
436
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
437
        }
438
439
        $this->assertDICConstructorArguments($definition, [
440
            new Reference('doctrine.dbal.default_connection'),
441
        new Reference('doctrine.orm.default_configuration'),
442
        ]);
443
444
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
445
        $this->assertEquals('%doctrine.orm.second_level_cache.default_cache_factory.class%', $slcDefinition->getClass());
446
    }
447
448
    public function testSingleEntityManagerWithCustomSecondLevelCacheConfiguration()
449
    {
450
        if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) {
451
            $this->markTestSkipped(sprintf('Second Level cache not supported by this version of the ORM : %s', Version::VERSION));
452
        }
453
        $container = $this->getContainer();
454
        $extension = new DoctrineExtension();
455
456
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
457
            ->addSecondLevelCache([
458
                'region_cache_driver' => ['type' => 'memcache'],
459
                'regions' => [
460
                    'hour_region' => ['lifetime' => 3600],
461
                ],
462
                'factory' => 'YamlBundle\Cache\MyCacheFactory',
463
            ])
464
            ->build();
465
466
        $extension->load([$configurationArray], $container);
467
        $this->compileContainer($container);
468
469
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
470
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
471 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
472
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
473
        } else {
474
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
475
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
476
        }
477
478
        $this->assertDICConstructorArguments($definition, [
479
            new Reference('doctrine.dbal.default_connection'),
480
        new Reference('doctrine.orm.default_configuration'),
481
        ]);
482
483
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
484
        $this->assertEquals('YamlBundle\Cache\MyCacheFactory', $slcDefinition->getClass());
485
    }
486
487 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...
488
    {
489
        $container = $this->getContainer();
490
        $extension = new DoctrineExtension();
491
492
        $config        = BundleConfigurationBuilder::createBuilder()
493
             ->addBaseConnection()
494
             ->build();
495
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => []]]]];
496
        $extension->load([$config], $container);
497
498
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
499
        $this->assertDICDefinitionMethodCallOnce(
500
            $definition,
501
            'setEntityNamespaces',
502
            [['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity']]
503
        );
504
    }
505
506 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...
507
    {
508
        $container = $this->getContainer();
509
        $extension = new DoctrineExtension();
510
511
        $config        = BundleConfigurationBuilder::createBuilder()
512
             ->addBaseConnection()
513
             ->build();
514
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => ['alias' => 'yml']]]]];
515
        $extension->load([$config], $container);
516
517
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
518
        $this->assertDICDefinitionMethodCallOnce(
519
            $definition,
520
            'setEntityNamespaces',
521
            [['yml' => 'Fixtures\Bundles\YamlBundle\Entity']]
522
        );
523
    }
524
525
    public function testYamlBundleMappingDetection()
526
    {
527
        $container = $this->getContainer('YamlBundle');
528
        $extension = new DoctrineExtension();
529
530
        $config = BundleConfigurationBuilder::createBuilder()
531
            ->addBaseConnection()
532
            ->addBaseEntityManager()
533
            ->build();
534
        $extension->load([$config], $container);
535
536
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
537
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
538
            new Reference('doctrine.orm.default_yml_metadata_driver'),
539
            'Fixtures\Bundles\YamlBundle\Entity',
540
        ]);
541
    }
542
543 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...
544
    {
545
        $container = $this->getContainer('XmlBundle');
546
        $extension = new DoctrineExtension();
547
548
        $config = BundleConfigurationBuilder::createBuilder()
549
            ->addBaseConnection()
550
            ->addEntityManager([
551
                'default_entity_manager' => 'default',
552
                'entity_managers' => [
553
                    'default' => [
554
                        'mappings' => [
555
                            'XmlBundle' => [],
556
                        ],
557
                    ],
558
                ],
559
            ])
560
            ->build();
561
        $extension->load([$config], $container);
562
563
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
564
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
565
            new Reference('doctrine.orm.default_xml_metadata_driver'),
566
            'Fixtures\Bundles\XmlBundle\Entity',
567
        ]);
568
    }
569
570 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...
571
    {
572
        $container = $this->getContainer('AnnotationsBundle');
573
        $extension = new DoctrineExtension();
574
575
        $config = BundleConfigurationBuilder::createBuilder()
576
            ->addBaseConnection()
577
            ->addEntityManager([
578
                'default_entity_manager' => 'default',
579
                'entity_managers' => [
580
                    'default' => [
581
                        'mappings' => [
582
                            'AnnotationsBundle' => [],
583
                        ],
584
                    ],
585
                ],
586
            ])
587
            ->build();
588
        $extension->load([$config], $container);
589
590
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
591
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
592
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
593
            'Fixtures\Bundles\AnnotationsBundle\Entity',
594
        ]);
595
    }
596
597
    public function testOrmMergeConfigs()
598
    {
599
        $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...
600
        $extension = new DoctrineExtension();
601
602
        $config1 = BundleConfigurationBuilder::createBuilder()
603
            ->addBaseConnection()
604
            ->addEntityManager([
605
                'auto_generate_proxy_classes' => true,
606
                'default_entity_manager' => 'default',
607
                'entity_managers' => [
608
                    'default' => [
609
                        'mappings' => [
610
                            'AnnotationsBundle' => [],
611
                        ],
612
                    ],
613
                ],
614
            ])
615
            ->build();
616
        $config2 = BundleConfigurationBuilder::createBuilder()
617
            ->addBaseConnection()
618
            ->addEntityManager([
619
                'auto_generate_proxy_classes' => false,
620
                'default_entity_manager' => 'default',
621
                'entity_managers' => [
622
                    'default' => [
623
                        'mappings' => [
624
                            'XmlBundle' => [],
625
                        ],
626
                    ],
627
                ],
628
            ])
629
            ->build();
630
        $extension->load([$config1, $config2], $container);
631
632
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
633
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
634
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
635
            'Fixtures\Bundles\AnnotationsBundle\Entity',
636
        ]);
637
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
638
            new Reference('doctrine.orm.default_xml_metadata_driver'),
639
            'Fixtures\Bundles\XmlBundle\Entity',
640
        ]);
641
642
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
643
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setAutoGenerateProxyClasses');
644
645
        $calls = $configDef->getMethodCalls();
646
        foreach ($calls as $call) {
647
            if ($call[0] === 'setAutoGenerateProxyClasses') {
648
                $this->assertFalse($container->getParameterBag()->resolveValue($call[1][0]));
649
                break;
650
            }
651
        }
652
    }
653
654
    public function testAnnotationsBundleMappingDetectionWithVendorNamespace()
655
    {
656
        $container = $this->getContainer('AnnotationsBundle', 'Vendor');
657
        $extension = new DoctrineExtension();
658
659
        $config = BundleConfigurationBuilder::createBuilder()
660
            ->addBaseConnection()
661
            ->addEntityManager([
662
                'default_entity_manager' => 'default',
663
                'entity_managers' => [
664
                    'default' => [
665
                        'mappings' => [
666
                            'AnnotationsBundle' => [],
667
                        ],
668
                    ],
669
                ],
670
            ])
671
            ->build();
672
        $extension->load([$config], $container);
673
674
        $calls = $container->getDefinition('doctrine.orm.default_metadata_driver')->getMethodCalls();
675
        $this->assertEquals('doctrine.orm.default_annotation_metadata_driver', (string) $calls[0][1][0]);
676
        $this->assertEquals('Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]);
677
    }
678
679
    public function testMessengerIntegration()
680
    {
681
        $container = $this->getContainer();
682
        $extension = new DoctrineExtension();
683
684
        $config = BundleConfigurationBuilder::createBuilder()
685
            ->addBaseConnection()
686
            ->addEntityManager([
687
                'default_entity_manager' => 'default',
688
                'entity_managers' => [
689
                    'default' => [],
690
                ],
691
            ])
692
            ->build();
693
        $extension->load([$config], $container);
694
695
        $this->assertNotNull($container->getDefinition('doctrine.orm.messenger.middleware_factory.transaction'));
696
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_transaction_middleware'));
697
        $this->assertSame('default', $middlewarePrototype->getArgument(0));
698
    }
699
700
    public function testCacheConfiguration()
701
    {
702
        $container = $this->getContainer();
703
        $extension = new DoctrineExtension();
704
705
        $config = BundleConfigurationBuilder::createBuilder()
706
             ->addBaseConnection()
707
             ->addEntityManager([
708
                 'metadata_cache_driver' => ['cache_provider' => 'metadata_cache'],
709
                 'query_cache_driver' => ['cache_provider' => 'query_cache'],
710
                 'result_cache_driver' => ['cache_provider' => 'result_cache'],
711
             ])
712
            ->build();
713
714
        $extension->load([$config], $container);
715
716
        $this->assertTrue($container->hasAlias('doctrine.orm.default_metadata_cache'));
717
        $alias = $container->getAlias('doctrine.orm.default_metadata_cache');
718
        $this->assertEquals('doctrine_cache.providers.metadata_cache', (string) $alias);
719
720
        $this->assertTrue($container->hasAlias('doctrine.orm.default_query_cache'));
721
        $alias = $container->getAlias('doctrine.orm.default_query_cache');
722
        $this->assertEquals('doctrine_cache.providers.query_cache', (string) $alias);
723
724
        $this->assertTrue($container->hasAlias('doctrine.orm.default_result_cache'));
725
        $alias = $container->getAlias('doctrine.orm.default_result_cache');
726
        $this->assertEquals('doctrine_cache.providers.result_cache', (string) $alias);
727
    }
728
729
    public function testShardManager()
730
    {
731
        $container = $this->getContainer();
732
        $extension = new DoctrineExtension();
733
734
        $config = BundleConfigurationBuilder::createBuilder()
735
             ->addConnection([
736
                 'connections' => [
737
                     'foo' => [
738
                         'shards' => [
739
                             'test' => ['id' => 1],
740
                         ],
741
                     ],
742
                     'bar' => [],
743
                 ],
744
             ])
745
            ->build();
746
747
        $extension->load([$config], $container);
748
749
        $this->assertTrue($container->hasDefinition('doctrine.dbal.foo_shard_manager'));
750
        $this->assertFalse($container->hasDefinition('doctrine.dbal.bar_shard_manager'));
751
    }
752
753
    private function getContainer($bundles = 'YamlBundle', $vendor = null)
754
    {
755
        $bundles = (array) $bundles;
756
757
        $map = [];
758
        foreach ($bundles as $bundle) {
759
            require_once __DIR__ . '/Fixtures/Bundles/' . ($vendor ? $vendor . '/' : '') . $bundle . '/' . $bundle . '.php';
760
761
            $map[$bundle] = 'Fixtures\\Bundles\\' . ($vendor ? $vendor . '\\' : '') . $bundle . '\\' . $bundle;
762
        }
763
764
        return new ContainerBuilder(new ParameterBag([
765
            'kernel.name' => 'app',
766
            'kernel.debug' => false,
767
            'kernel.bundles' => $map,
768
            'kernel.cache_dir' => sys_get_temp_dir(),
769
            'kernel.environment' => 'test',
770
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
771
        ]));
772
    }
773
774
    private function assertDICConstructorArguments(Definition $definition, array $args)
775
    {
776
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
777
    }
778
779 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...
780
    {
781
        $calls = $definition->getMethodCalls();
782
        if (! isset($calls[$pos][0])) {
783
            return;
784
        }
785
786
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
787
788
        if ($params === null) {
789
            return;
790
        }
791
792
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
793
    }
794
795
    /**
796
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
797
     *
798
     * @param string     $methodName
799
     * @param array|null $params
800
     */
801 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...
802
    {
803
        $calls  = $definition->getMethodCalls();
804
        $called = false;
805
        foreach ($calls as $call) {
806
            if ($call[0] !== $methodName) {
807
                continue;
808
            }
809
810
            if ($called) {
811
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
812
            } else {
813
                $called = true;
814
                if ($params !== null) {
815
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
816
                }
817
            }
818
        }
819
        if ($called) {
820
            return;
821
        }
822
823
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
824
    }
825
826
    private function compileContainer(ContainerBuilder $container)
827
    {
828
        $container->getCompilerPassConfig()->setOptimizationPasses([class_exists(ResolveChildDefinitionsPass::class) ? new ResolveChildDefinitionsPass() : new ResolveDefinitionTemplatesPass()]);
0 ignored issues
show
Documentation introduced by
array(class_exists(\Symf...initionTemplatesPass()) is of type array<integer,object<Sym...nitionTemplatesPass>"}>, but the function expects a array<integer,object<Sym...CompilerPassInterface>>.

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...
829
        $container->getCompilerPassConfig()->setRemovingPasses([]);
830
        $container->compile();
831
    }
832
}
833
834
class TestWrapperClass extends Connection
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
835
{
836
}
837