Completed
Pull Request — master (#1040)
by Andreas
01:42
created

testDbalSchemaFilterNewConfig()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 9.248
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\Compiler\DbalSchemaFilterPass;
6
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
7
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\WellKnownSchemaFilterPass;
8
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
9
use Doctrine\DBAL\Configuration;
10
use Doctrine\DBAL\Schema\AbstractAsset;
11
use Doctrine\ORM\EntityManager;
12
use PHPUnit\Framework\TestCase;
13
use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass;
14
use Symfony\Component\Cache\Adapter\ArrayAdapter;
15
use Symfony\Component\Cache\DoctrineProvider;
16
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
18
use Symfony\Component\DependencyInjection\ContainerBuilder;
19
use Symfony\Component\DependencyInjection\Definition;
20
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
21
use Symfony\Component\DependencyInjection\Reference;
22
use Symfony\Component\DependencyInjection\ServiceLocator;
23
24
abstract class AbstractDoctrineExtensionTest extends TestCase
25
{
26
    abstract protected function loadFromFile(ContainerBuilder $container, $file);
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
27
28
    public function testDbalLoadFromXmlMultipleConnections()
29
    {
30
        $container = $this->loadContainer('dbal_service_multiple_connections');
31
32
        // doctrine.dbal.mysql_connection
33
        $config = $container->getDefinition('doctrine.dbal.mysql_connection')->getArgument(0);
34
35
        $this->assertEquals('mysql_s3cr3t', $config['password']);
36
        $this->assertEquals('mysql_user', $config['user']);
37
        $this->assertEquals('mysql_db', $config['dbname']);
38
        $this->assertEquals('/path/to/mysqld.sock', $config['unix_socket']);
39
40
        // doctrine.dbal.sqlite_connection
41
        $config = $container->getDefinition('doctrine.dbal.sqlite_connection')->getArgument(0);
42
        $this->assertSame('pdo_sqlite', $config['driver']);
43
        $this->assertSame('sqlite_db', $config['dbname']);
44
        $this->assertSame('sqlite_user', $config['user']);
45
        $this->assertSame('sqlite_s3cr3t', $config['password']);
46
        $this->assertSame('/tmp/db.sqlite', $config['path']);
47
        $this->assertTrue($config['memory']);
48
49
        // doctrine.dbal.oci8_connection
50
        $config = $container->getDefinition('doctrine.dbal.oci_connection')->getArgument(0);
51
        $this->assertSame('oci8', $config['driver']);
52
        $this->assertSame('oracle_db', $config['dbname']);
53
        $this->assertSame('oracle_user', $config['user']);
54
        $this->assertSame('oracle_s3cr3t', $config['password']);
55
        $this->assertSame('oracle_service', $config['servicename']);
56
        $this->assertTrue($config['service']);
57
        $this->assertTrue($config['pooled']);
58
        $this->assertSame('utf8', $config['charset']);
59
60
        // doctrine.dbal.ibmdb2_connection
61
        $config = $container->getDefinition('doctrine.dbal.ibmdb2_connection')->getArgument(0);
62
        $this->assertSame('ibm_db2', $config['driver']);
63
        $this->assertSame('ibmdb2_db', $config['dbname']);
64
        $this->assertSame('ibmdb2_user', $config['user']);
65
        $this->assertSame('ibmdb2_s3cr3t', $config['password']);
66
        $this->assertSame('TCPIP', $config['protocol']);
67
68
        // doctrine.dbal.pgsql_connection
69
        $config = $container->getDefinition('doctrine.dbal.pgsql_connection')->getArgument(0);
70
        $this->assertSame('pdo_pgsql', $config['driver']);
71
        $this->assertSame('pgsql_schema', $config['dbname']);
72
        $this->assertSame('pgsql_user', $config['user']);
73
        $this->assertSame('pgsql_s3cr3t', $config['password']);
74
        $this->assertSame('pgsql_db', $config['default_dbname']);
75
        $this->assertSame('require', $config['sslmode']);
76
        $this->assertSame('postgresql-ca.pem', $config['sslrootcert']);
77
        $this->assertSame('postgresql-cert.pem', $config['sslcert']);
78
        $this->assertSame('postgresql-key.pem', $config['sslkey']);
79
        $this->assertSame('postgresql.crl', $config['sslcrl']);
80
        $this->assertSame('utf8', $config['charset']);
81
82
        // doctrine.dbal.sqlanywhere_connection
83
        $config = $container->getDefinition('doctrine.dbal.sqlanywhere_connection')->getArgument(0);
84
        $this->assertSame('sqlanywhere', $config['driver']);
85
        $this->assertSame('localhost', $config['host']);
86
        $this->assertSame(2683, $config['port']);
87
        $this->assertSame('sqlanywhere_server', $config['server']);
88
        $this->assertSame('sqlanywhere_db', $config['dbname']);
89
        $this->assertSame('sqlanywhere_user', $config['user']);
90
        $this->assertSame('sqlanywhere_s3cr3t', $config['password']);
91
        $this->assertTrue($config['persistent']);
92
        $this->assertSame('utf8', $config['charset']);
93
    }
94
95
    public function testDbalLoadFromXmlSingleConnections()
96
    {
97
        $container = $this->loadContainer('dbal_service_single_connection');
98
99
        // doctrine.dbal.mysql_connection
100
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
101
102
        $this->assertEquals('mysql_s3cr3t', $config['password']);
103
        $this->assertEquals('mysql_user', $config['user']);
104
        $this->assertEquals('mysql_db', $config['dbname']);
105
        $this->assertEquals('/path/to/mysqld.sock', $config['unix_socket']);
106
        $this->assertEquals('5.6.20', $config['serverVersion']);
107
    }
108
109
    public function testDbalLoadSingleMasterSlaveConnection()
110
    {
111
        $container = $this->loadContainer('dbal_service_single_master_slave_connection');
112
113
        // doctrine.dbal.mysql_connection
114
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
115
116
        $this->assertEquals('Doctrine\\DBAL\\Connections\\MasterSlaveConnection', $param['wrapperClass']);
117
        $this->assertTrue($param['keepSlave']);
118
        $this->assertEquals(
119
            [
120
                'user' => 'mysql_user',
121
                'password' => 'mysql_s3cr3t',
122
                'port' => null,
123
                'dbname' => 'mysql_db',
124
                'host' => 'localhost',
125
                'unix_socket' => '/path/to/mysqld.sock',
126
            ],
127
            $param['master']
128
        );
129
        $this->assertEquals(
130
            [
131
                'user' => 'slave_user',
132
                'password' => 'slave_s3cr3t',
133
                'port' => null,
134
                'dbname' => 'slave_db',
135
                'host' => 'localhost',
136
                'unix_socket' => '/path/to/mysqld_slave.sock',
137
            ],
138
            $param['slaves']['slave1']
139
        );
140
        $this->assertEquals(['engine' => 'InnoDB'], $param['defaultTableOptions']);
141
    }
142
143
    public function testDbalLoadPoolShardingConnection()
144
    {
145
        $container = $this->loadContainer('dbal_service_pool_sharding_connection');
146
147
        // doctrine.dbal.mysql_connection
148
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
149
150
        $this->assertEquals('Doctrine\\DBAL\\Sharding\\PoolingShardConnection', $param['wrapperClass']);
151
        $this->assertEquals(new Reference('foo.shard_choser'), $param['shardChoser']);
152
        $this->assertEquals(
153
            [
154
                'user' => 'mysql_user',
155
                'password' => 'mysql_s3cr3t',
156
                'port' => null,
157
                'dbname' => 'mysql_db',
158
                'host' => 'localhost',
159
                'unix_socket' => '/path/to/mysqld.sock',
160
            ],
161
            $param['global']
162
        );
163
        $this->assertEquals(
164
            [
165
                'user' => 'shard_user',
166
                'password' => 'shard_s3cr3t',
167
                'port' => null,
168
                'dbname' => 'shard_db',
169
                'host' => 'localhost',
170
                'unix_socket' => '/path/to/mysqld_shard.sock',
171
                'id' => 1,
172
            ],
173
            $param['shards'][0]
174
        );
175
        $this->assertEquals(['engine' => 'InnoDB'], $param['defaultTableOptions']);
176
    }
177
178
    public function testDbalLoadSavepointsForNestedTransactions()
179
    {
180
        $container = $this->loadContainer('dbal_savepoints');
181
182
        $calls = $container->getDefinition('doctrine.dbal.savepoints_connection')->getMethodCalls();
183
        $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...
184
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
185
        $this->assertTrue($calls[0][1][0]);
186
187
        $calls = $container->getDefinition('doctrine.dbal.nosavepoints_connection')->getMethodCalls();
188
        $this->assertCount(0, $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...
189
190
        $calls = $container->getDefinition('doctrine.dbal.notset_connection')->getMethodCalls();
191
        $this->assertCount(0, $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...
192
    }
193
194
    public function testLoadSimpleSingleConnection()
195
    {
196
        $container = $this->loadContainer('orm_service_simple_single_entity_manager');
197
198
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
199
200
        $this->assertDICConstructorArguments($definition, [
201
            [
202
                'dbname' => 'db',
203
                'host' => 'localhost',
204
                'port' => null,
205
                'user' => 'root',
206
                'password' => null,
207
                'driver' => 'pdo_mysql',
208
                'driverOptions' => [],
209
                'defaultTableOptions' => [],
210
            ],
211
            new Reference('doctrine.dbal.default_connection.configuration'),
212
            new Reference('doctrine.dbal.default_connection.event_manager'),
213
            [],
214
        ]);
215
216
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
217
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
218
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
219
220
        $this->assertDICConstructorArguments($definition, [
221
            new Reference('doctrine.dbal.default_connection'),
222
            new Reference('doctrine.orm.default_configuration'),
223
        ]);
224
    }
225
226
    /**
227
     * The PDO driver doesn't require a database name to be to set when connecting to a database server
228
     */
229
    public function testLoadSimpleSingleConnectionWithoutDbName()
230
    {
231
        $container = $this->loadContainer('orm_service_simple_single_entity_manager_without_dbname');
232
233
        /** @var Definition $definition */
234
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
235
236
        $this->assertDICConstructorArguments($definition, [
237
            [
238
                'host' => 'localhost',
239
                'port' => null,
240
                'user' => 'root',
241
                'password' => null,
242
                'driver' => 'pdo_mysql',
243
                'driverOptions' => [],
244
                'defaultTableOptions' => [],
245
            ],
246
            new Reference('doctrine.dbal.default_connection.configuration'),
247
            new Reference('doctrine.dbal.default_connection.event_manager'),
248
            [],
249
        ]);
250
251
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
252
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
253
        $factory = $definition->getFactory();
254
255
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $factory[0]);
256
        $this->assertEquals('create', $factory[1]);
257
258
        $this->assertDICConstructorArguments($definition, [
259
            new Reference('doctrine.dbal.default_connection'),
260
            new Reference('doctrine.orm.default_configuration'),
261
        ]);
262
    }
263
264
    public function testLoadSingleConnection()
265
    {
266
        $container = $this->loadContainer('orm_service_single_entity_manager');
267
268
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
269
270
        $this->assertDICConstructorArguments($definition, [
271
            [
272
                'host' => 'localhost',
273
                'driver' => 'pdo_sqlite',
274
                'driverOptions' => [],
275
                'user' => 'sqlite_user',
276
                'port' => null,
277
                'password' => 'sqlite_s3cr3t',
278
                'dbname' => 'sqlite_db',
279
                'memory' => true,
280
                'defaultTableOptions' => [],
281
            ],
282
            new Reference('doctrine.dbal.default_connection.configuration'),
283
            new Reference('doctrine.dbal.default_connection.event_manager'),
284
            [],
285
        ]);
286
287
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
288
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
289
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
290
291
        $this->assertDICConstructorArguments($definition, [
292
            new Reference('doctrine.dbal.default_connection'),
293
            new Reference('doctrine.orm.default_configuration'),
294
        ]);
295
296
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
297
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setDefaultRepositoryClassName', ['Acme\Doctrine\Repository']);
298
    }
299
300
    public function testLoadMultipleConnections()
301
    {
302
        $container = $this->loadContainer('orm_service_multiple_entity_managers');
303
304
        $definition = $container->getDefinition('doctrine.dbal.conn1_connection');
305
306
        $args = $definition->getArguments();
307
        $this->assertEquals('pdo_sqlite', $args[0]['driver']);
308
        $this->assertEquals('localhost', $args[0]['host']);
309
        $this->assertEquals('sqlite_user', $args[0]['user']);
310
        $this->assertEquals('doctrine.dbal.conn1_connection.configuration', (string) $args[1]);
311
        $this->assertEquals('doctrine.dbal.conn1_connection.event_manager', (string) $args[2]);
312
313
        $this->assertEquals('doctrine.orm.em2_entity_manager', (string) $container->getAlias('doctrine.orm.entity_manager'));
314
315
        $definition = $container->getDefinition('doctrine.orm.em1_entity_manager');
316
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
317
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
318
319
        $arguments = $definition->getArguments();
320
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
321
        $this->assertEquals('doctrine.dbal.conn1_connection', (string) $arguments[0]);
322
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
323
        $this->assertEquals('doctrine.orm.em1_configuration', (string) $arguments[1]);
324
325
        $definition = $container->getDefinition('doctrine.dbal.conn2_connection');
326
327
        $args = $definition->getArguments();
328
        $this->assertEquals('pdo_sqlite', $args[0]['driver']);
329
        $this->assertEquals('localhost', $args[0]['host']);
330
        $this->assertEquals('sqlite_user', $args[0]['user']);
331
        $this->assertEquals('doctrine.dbal.conn2_connection.configuration', (string) $args[1]);
332
        $this->assertEquals('doctrine.dbal.conn2_connection.event_manager', (string) $args[2]);
333
334
        $definition = $container->getDefinition('doctrine.orm.em2_entity_manager');
335
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
336
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
337
338
        $arguments = $definition->getArguments();
339
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
340
        $this->assertEquals('doctrine.dbal.conn2_connection', (string) $arguments[0]);
341
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
342
        $this->assertEquals('doctrine.orm.em2_configuration', (string) $arguments[1]);
343
344
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
345
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
346
347
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_query_cache'));
348
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
349
        $arguments = $definition->getArguments();
350
        $this->assertInstanceOf(Reference::class, $arguments[0]);
351
        $this->assertEquals('cache.app', (string) $arguments[0]);
352
353
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_result_cache'));
354
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
355
        $arguments = $definition->getArguments();
356
        $this->assertInstanceOf(Reference::class, $arguments[0]);
357
        $this->assertEquals('cache.app', (string) $arguments[0]);
358
    }
359
360
    public function testLoadLogging()
361
    {
362
        $container = $this->loadContainer('dbal_logging');
363
364
        $definition = $container->getDefinition('doctrine.dbal.log_connection.configuration');
365
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger')]);
366
367
        $definition = $container->getDefinition('doctrine.dbal.profile_connection.configuration');
368
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.profiling.profile')]);
369
370
        $definition = $container->getDefinition('doctrine.dbal.profile_with_backtrace_connection.configuration');
371
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.backtrace.profile_with_backtrace')]);
372
373
        $definition = $container->getDefinition('doctrine.dbal.backtrace_without_profile_connection.configuration');
374
        $this->assertDICDefinitionNoMethodCall($definition, 'setSQLLogger');
375
376
        $definition = $container->getDefinition('doctrine.dbal.both_connection.configuration');
377
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.chain.both')]);
378
    }
379
380
    public function testEntityManagerMetadataCacheDriverConfiguration()
381
    {
382
        $container = $this->loadContainer('orm_service_multiple_entity_managers');
383
384
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
385
        $this->assertDICDefinitionClass($definition, DoctrineProvider::class);
386
387
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em2_metadata_cache'));
388
        $this->assertDICDefinitionClass($definition, DoctrineProvider::class);
389
    }
390
391
    public function testDependencyInjectionImportsOverrideDefaults()
392
    {
393
        $container = $this->loadContainer('orm_imports');
394
395
        $cacheDefinition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
396
        $this->assertEquals(DoctrineProvider::class, $cacheDefinition->getClass());
397
398
        $configDefinition = $container->getDefinition('doctrine.orm.default_configuration');
399
        $this->assertDICDefinitionMethodCallOnce($configDefinition, 'setAutoGenerateProxyClasses', ['%doctrine.orm.auto_generate_proxy_classes%']);
400
    }
401
402
    public function testSingleEntityManagerMultipleMappingBundleDefinitions()
403
    {
404
        $container = $this->loadContainer('orm_single_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
405
406
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
407
408
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
409
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
410
            'Fixtures\Bundles\AnnotationsBundle\Entity',
411
        ]);
412
413
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
414
            new Reference('doctrine.orm.default_yml_metadata_driver'),
415
            'Fixtures\Bundles\YamlBundle\Entity',
416
        ]);
417
418
        $this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', [
419
            new Reference('doctrine.orm.default_xml_metadata_driver'),
420
            'Fixtures\Bundles\XmlBundle',
421
        ]);
422
423
        $annDef = $container->getDefinition('doctrine.orm.default_annotation_metadata_driver');
424
        $this->assertDICConstructorArguments($annDef, [
425
            new Reference('doctrine.orm.metadata.annotation_reader'),
426
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
427
        ]);
428
429
        $ymlDef = $container->getDefinition('doctrine.orm.default_yml_metadata_driver');
430
        $this->assertDICConstructorArguments($ymlDef, [
431
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
432
        ]);
433
434
        $xmlDef = $container->getDefinition('doctrine.orm.default_xml_metadata_driver');
435
        $this->assertDICConstructorArguments($xmlDef, [
436
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
437
        ]);
438
    }
439
440
    public function testMultipleEntityManagersMappingBundleDefinitions()
441
    {
442
        $container = $this->loadContainer('orm_multiple_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
443
444
        $this->assertEquals(['em1' => 'doctrine.orm.em1_entity_manager', 'em2' => 'doctrine.orm.em2_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
445
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
446
447
        $def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver');
448
        $def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver');
449
450
        $this->assertDICDefinitionMethodCallAt(0, $def1, 'addDriver', [
451
            new Reference('doctrine.orm.em1_annotation_metadata_driver'),
452
            'Fixtures\Bundles\AnnotationsBundle\Entity',
453
        ]);
454
455
        $this->assertDICDefinitionMethodCallAt(0, $def2, 'addDriver', [
456
            new Reference('doctrine.orm.em2_yml_metadata_driver'),
457
            'Fixtures\Bundles\YamlBundle\Entity',
458
        ]);
459
460
        $this->assertDICDefinitionMethodCallAt(1, $def2, 'addDriver', [
461
            new Reference('doctrine.orm.em2_xml_metadata_driver'),
462
            'Fixtures\Bundles\XmlBundle',
463
        ]);
464
465
        $annDef = $container->getDefinition('doctrine.orm.em1_annotation_metadata_driver');
466
        $this->assertDICConstructorArguments($annDef, [
467
            new Reference('doctrine.orm.metadata.annotation_reader'),
468
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
469
        ]);
470
471
        $ymlDef = $container->getDefinition('doctrine.orm.em2_yml_metadata_driver');
472
        $this->assertDICConstructorArguments($ymlDef, [
473
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
474
        ]);
475
476
        $xmlDef = $container->getDefinition('doctrine.orm.em2_xml_metadata_driver');
477
        $this->assertDICConstructorArguments($xmlDef, [
478
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
479
        ]);
480
    }
481
482
    public function testSingleEntityManagerDefaultTableOptions()
483
    {
484
        $container = $this->loadContainer('orm_single_em_default_table_options', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
485
486
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
487
488
        $this->assertArrayHasKey('defaultTableOptions', $param);
489
490
        $defaults = $param['defaultTableOptions'];
491
492
        $this->assertArrayHasKey('charset', $defaults);
493
        $this->assertArrayHasKey('collate', $defaults);
494
        $this->assertArrayHasKey('engine', $defaults);
495
496
        $this->assertEquals('utf8mb4', $defaults['charset']);
497
        $this->assertEquals('utf8mb4_unicode_ci', $defaults['collate']);
498
        $this->assertEquals('InnoDB', $defaults['engine']);
499
    }
500
501
    public function testSetTypes()
502
    {
503
        $container = $this->loadContainer('dbal_types');
504
505
        $this->assertEquals(
506
            ['test' => ['class' => TestType::class]],
507
            $container->getParameter('doctrine.dbal.connection_factory.types')
508
        );
509
        $this->assertEquals('%doctrine.dbal.connection_factory.types%', $container->getDefinition('doctrine.dbal.connection_factory')->getArgument(0));
510
    }
511
512
    public function testSetCustomFunctions()
513
    {
514
        $container = $this->loadContainer('orm_functions');
515
516
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
517
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
518
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomNumericFunction', ['test_numeric', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction']);
519
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomDatetimeFunction', ['test_datetime', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction']);
520
    }
521
522 View Code Duplication
    public function testSetNamingStrategy()
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...
523
    {
524
        $container = $this->loadContainer('orm_namingstrategy');
525
526
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
527
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
528
529
        $this->assertDICDefinitionMethodCallOnce($def1, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.default')]);
530
        $this->assertDICDefinitionMethodCallOnce($def2, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.underscore')]);
531
    }
532
533 View Code Duplication
    public function testSetQuoteStrategy()
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...
534
    {
535
        $container = $this->loadContainer('orm_quotestrategy');
536
537
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
538
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
539
540
        $this->assertDICDefinitionMethodCallOnce($def1, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.default')]);
541
        $this->assertDICDefinitionMethodCallOnce($def2, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.ansi')]);
542
    }
543
544
    public function testSecondLevelCache()
545
    {
546
        $container = $this->loadContainer('orm_second_level_cache');
547
548
        $this->assertTrue($container->has('doctrine.orm.default_configuration'));
549
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.cache_configuration'));
550
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region_cache_driver'));
551
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.regions_configuration'));
552
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.default_cache_factory'));
553
554
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_chain'));
555
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_statistics'));
556
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger1'));
557
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger2'));
558
559
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_entity_region'));
560
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_service_region'));
561
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_query_region_filelock'));
562
563
        $slcFactoryDef       = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
564
        $myEntityRegionDef   = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_entity_region');
565
        $loggerChainDef      = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_chain');
566
        $loggerStatisticsDef = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_statistics');
567
        $myQueryRegionDef    = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_query_region_filelock');
568
        $cacheDriverDef      = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_second_level_cache.region_cache_driver'));
569
        $configDef           = $container->getDefinition('doctrine.orm.default_configuration');
570
        $myEntityRegionArgs  = $myEntityRegionDef->getArguments();
571
        $myQueryRegionArgs   = $myQueryRegionDef->getArguments();
572
        $slcFactoryArgs      = $slcFactoryDef->getArguments();
573
574
        $this->assertDICDefinitionClass($slcFactoryDef, '%doctrine.orm.second_level_cache.default_cache_factory.class%');
575
        $this->assertDICDefinitionClass($myQueryRegionDef, '%doctrine.orm.second_level_cache.filelock_region.class%');
576
        $this->assertDICDefinitionClass($myEntityRegionDef, '%doctrine.orm.second_level_cache.default_region.class%');
577
        $this->assertDICDefinitionClass($loggerChainDef, '%doctrine.orm.second_level_cache.logger_chain.class%');
578
        $this->assertDICDefinitionClass($loggerStatisticsDef, '%doctrine.orm.second_level_cache.logger_statistics.class%');
579
        $this->assertDICDefinitionClass($cacheDriverDef, DoctrineProvider::class);
580
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setSecondLevelCacheConfiguration');
581
        $this->assertDICDefinitionMethodCallCount($slcFactoryDef, 'setRegion', [], 3);
582
        $this->assertDICDefinitionMethodCallCount($loggerChainDef, 'setLogger', [], 3);
583
584
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[0]);
585
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[1]);
586
587
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myEntityRegionArgs[1]);
588
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myQueryRegionArgs[0]);
589
590
        $this->assertEquals('my_entity_region', $myEntityRegionArgs[0]);
591
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_entity_region_driver', $myEntityRegionArgs[1]);
592
        $this->assertEquals(600, $myEntityRegionArgs[2]);
593
594
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_query_region', $myQueryRegionArgs[0]);
595
        $this->assertContains('/doctrine/orm/slc/filelock', $myQueryRegionArgs[1]);
596
        $this->assertEquals(60, $myQueryRegionArgs[2]);
597
598
        $this->assertEquals('doctrine.orm.default_second_level_cache.regions_configuration', $slcFactoryArgs[0]);
599
        $this->assertEquals('doctrine.orm.default_second_level_cache.region_cache_driver', $slcFactoryArgs[1]);
600
    }
601
602
    public function testSingleEMSetCustomFunctions()
603
    {
604
        $container = $this->loadContainer('orm_single_em_dql_functions');
605
606
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
607
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
608
    }
609
610
    public function testAddCustomHydrationMode()
611
    {
612
        $container = $this->loadContainer('orm_hydration_mode');
613
614
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
615
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomHydrationMode', ['test_hydrator', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator']);
616
    }
617
618
    public function testAddFilter()
619
    {
620
        $container = $this->loadContainer('orm_filters');
621
622
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
623
        $args       = [
624
            ['soft_delete', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
625
            ['myFilter', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
626
        ];
627
        $this->assertDICDefinitionMethodCallCount($definition, 'addFilter', $args, 2);
628
629
        $definition = $container->getDefinition('doctrine.orm.default_manager_configurator');
630
        $this->assertDICConstructorArguments($definition, [['soft_delete', 'myFilter'], ['myFilter' => ['myParameter' => 'myValue', 'mySecondParameter' => 'mySecondValue']]]);
631
632
        // Let's create the instance to check the configurator work.
633
        /** @var EntityManager $entityManager */
634
        $entityManager = $container->get('doctrine.orm.entity_manager');
635
        $this->assertCount(2, $entityManager->getFilters()->getEnabledFilters());
0 ignored issues
show
Documentation introduced by
$entityManager->getFilters()->getEnabledFilters() is of type array<integer,object<Doc...uery\Filter\SQLFilter>>, 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...
636
    }
637
638
    public function testResolveTargetEntity()
639
    {
640
        $container = $this->loadContainer('orm_resolve_target_entity');
641
642
        $definition = $container->getDefinition('doctrine.orm.listeners.resolve_target_entity');
643
        $this->assertDICDefinitionMethodCallOnce($definition, 'addResolveTargetEntity', ['Symfony\Component\Security\Core\User\UserInterface', 'MyUserClass', []]);
644
645
        $this->assertEquals(['doctrine.event_subscriber' => [[]]], $definition->getTags());
646
    }
647
648
    public function testAttachEntityListeners()
649
    {
650
        $container = $this->loadContainer('orm_attach_entity_listener');
651
652
        $definition  = $container->getDefinition('doctrine.orm.default_listeners.attach_entity_listeners');
653
        $methodCalls = $definition->getMethodCalls();
654
655
        $this->assertDICDefinitionMethodCallCount($definition, 'addEntityListener', [], 6);
656
        $this->assertEquals(['doctrine.event_listener' => [ ['event' => 'loadClassMetadata'] ] ], $definition->getTags());
657
658
        $this->assertEquals($methodCalls[0], [
659
            'addEntityListener',
660
            [
661
                'ExternalBundles\Entities\FooEntity',
662
                'MyBundles\Listeners\FooEntityListener',
663
                'prePersist',
664
                null,
665
            ],
666
        ]);
667
668
        $this->assertEquals($methodCalls[1], [
669
            'addEntityListener',
670
            [
671
                'ExternalBundles\Entities\FooEntity',
672
                'MyBundles\Listeners\FooEntityListener',
673
                'postPersist',
674
                'postPersist',
675
            ],
676
        ]);
677
678
        $this->assertEquals($methodCalls[2], [
679
            'addEntityListener',
680
            [
681
                'ExternalBundles\Entities\FooEntity',
682
                'MyBundles\Listeners\FooEntityListener',
683
                'postLoad',
684
                'postLoadHandler',
685
            ],
686
        ]);
687
688
        $this->assertEquals($methodCalls[3], [
689
            'addEntityListener',
690
            [
691
                'ExternalBundles\Entities\BarEntity',
692
                'MyBundles\Listeners\BarEntityListener',
693
                'prePersist',
694
                'prePersist',
695
            ],
696
        ]);
697
698
        $this->assertEquals($methodCalls[4], [
699
            'addEntityListener',
700
            [
701
                'ExternalBundles\Entities\BarEntity',
702
                'MyBundles\Listeners\BarEntityListener',
703
                'prePersist',
704
                'prePersistHandler',
705
            ],
706
        ]);
707
708
        $this->assertEquals($methodCalls[5], [
709
            'addEntityListener',
710
            [
711
                'ExternalBundles\Entities\BarEntity',
712
                'MyBundles\Listeners\LogDeleteEntityListener',
713
                'postDelete',
714
                'postDelete',
715
            ],
716
        ]);
717
    }
718
719
    public function testDbalAutoCommit()
720
    {
721
        $container = $this->loadContainer('dbal_auto_commit');
722
723
        $definition = $container->getDefinition('doctrine.dbal.default_connection.configuration');
724
        $this->assertDICDefinitionMethodCallOnce($definition, 'setAutoCommit', [false]);
725
    }
726
727
    public function testDbalOracleConnectstring()
728
    {
729
        $container = $this->loadContainer('dbal_oracle_connectstring');
730
731
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
732
        $this->assertSame('scott@sales-server:1521/sales.us.example.com', $config['connectstring']);
733
    }
734
735
    public function testDbalOracleInstancename()
736
    {
737
        $container = $this->loadContainer('dbal_oracle_instancename');
738
739
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
740
        $this->assertSame('mySuperInstance', $config['instancename']);
741
    }
742
743
    public function testDbalSchemaFilterNewConfig()
744
    {
745
        $container = $this->getContainer([]);
746
        $loader    = new DoctrineExtension();
747
        $container->registerExtension($loader);
748
        $container->addCompilerPass(new WellKnownSchemaFilterPass());
749
        $container->addCompilerPass(new DbalSchemaFilterPass());
750
751
        // ignore table1 table on "default" connection
752
        $container->register('dummy_filter1', DummySchemaAssetsFilter::class)
753
            ->setArguments(['table1'])
754
            ->addTag('doctrine.dbal.schema_filter');
755
756
        // ignore table2 table on "connection2" connection
757
        $container->register('dummy_filter2', DummySchemaAssetsFilter::class)
758
            ->setArguments(['table2'])
759
            ->addTag('doctrine.dbal.schema_filter', ['connection' => 'connection2']);
760
761
        $this->loadFromFile($container, 'dbal_schema_filter');
762
763
        $assetNames               = ['table1', 'table2', 'table3', 't_ignored'];
764
        $expectedConnectionAssets = [
765
            // ignores table1 + schema_filter applies
766
            'connection1' => ['table2', 'table3'],
767
            // ignores table2, no schema_filter applies
768
            'connection2' => ['table1', 'table3', 't_ignored'],
769
            // connection3 has no ignores, handled separately
770
        ];
771
772
        $this->compileContainer($container);
773
774
        $getConfiguration = static function (string $connectionName) use ($container) : Configuration {
775
            return $container->get(sprintf('doctrine.dbal.%s_connection', $connectionName))->getConfiguration();
776
        };
777
778
        foreach ($expectedConnectionAssets as $connectionName => $expectedTables) {
779
            $connConfig = $getConfiguration($connectionName);
780
            $this->assertSame($expectedTables, array_values(array_filter($assetNames, $connConfig->getSchemaAssetsFilter())), sprintf('Filtering for connection "%s"', $connectionName));
781
        }
782
783
        $this->assertNull($connConfig = $getConfiguration('connection3')->getSchemaAssetsFilter());
784
    }
785
786
    public function testWellKnownSchemaFilterDefaultTables()
787
    {
788
        $container = $this->getContainer([]);
789
        $loader    = new DoctrineExtension();
790
        $container->registerExtension($loader);
791
        $container->addCompilerPass(new WellKnownSchemaFilterPass());
792
        $container->addCompilerPass(new DbalSchemaFilterPass());
793
794
        $this->loadFromFile($container, 'well_known_schema_filter_default_tables');
795
796
        $this->compileContainer($container);
797
798
        $definition = $container->getDefinition('doctrine.dbal.well_known_schema_asset_filter');
799
800
        $this->assertSame([['cache_items', 'lock_keys', 'sessions', 'messenger_messages']], $definition->getArguments());
801
        $this->assertSame([['connection' => 'connection1'], ['connection' => 'connection2'], ['connection' => 'connection3']], $definition->getTag('doctrine.dbal.schema_filter'));
802
803
        $definition = $container->getDefinition('doctrine.dbal.connection1_schema_asset_filter_manager');
804
805
        $this->assertEquals([new Reference('doctrine.dbal.well_known_schema_asset_filter'), new Reference('doctrine.dbal.connection1_regex_schema_filter')], $definition->getArgument(0));
806
807
        $filter = $container->get('well_known_filter');
808
809
        $this->assertFalse($filter('sessions'));
810
        $this->assertFalse($filter('cache_items'));
811
        $this->assertFalse($filter('lock_keys'));
812
        $this->assertFalse($filter('messenger_messages'));
813
        $this->assertTrue($filter('anything_else'));
814
    }
815
816
    public function testWellKnownSchemaFilterOverriddenTables()
817
    {
818
        $container = $this->getContainer([]);
819
        $loader    = new DoctrineExtension();
820
        $container->registerExtension($loader);
821
        $container->addCompilerPass(new WellKnownSchemaFilterPass());
822
        $container->addCompilerPass(new DbalSchemaFilterPass());
823
824
        $this->loadFromFile($container, 'well_known_schema_filter_overridden_tables');
825
826
        $this->compileContainer($container);
827
828
        $filter = $container->get('well_known_filter');
829
830
        $this->assertFalse($filter('app_session'));
831
        $this->assertFalse($filter('app_cache'));
832
        $this->assertFalse($filter('app_locks'));
833
        $this->assertFalse($filter('app_messages'));
834
        $this->assertTrue($filter('sessions'));
835
        $this->assertTrue($filter('cache_items'));
836
        $this->assertTrue($filter('lock_keys'));
837
        $this->assertTrue($filter('messenger_messages'));
838
    }
839
840
    public function testEntityListenerResolver()
841
    {
842
        $container = $this->loadContainer('orm_entity_listener_resolver', ['YamlBundle'], new EntityListenerPass());
843
844
        $definition = $container->getDefinition('doctrine.orm.em1_configuration');
845
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em1_entity_listener_resolver')]);
846
847
        $definition = $container->getDefinition('doctrine.orm.em2_configuration');
848
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em2_entity_listener_resolver')]);
849
850
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
851
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener', 'entity_listener1']);
852
853
        $listener = $container->getDefinition('entity_listener_resolver');
854
        $this->assertDICDefinitionMethodCallOnce($listener, 'register', [new Reference('entity_listener2')]);
855
    }
856
857
    public function testAttachEntityListenerTag()
858
    {
859
        $container = $this->getContainer([]);
860
        $loader    = new DoctrineExtension();
861
        $container->registerExtension($loader);
862
        $container->addCompilerPass(new EntityListenerPass());
863
864
        $this->loadFromFile($container, 'orm_attach_entity_listener_tag');
865
866
        $this->compileContainer($container);
867
868
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
869
        $this->assertDICDefinitionMethodCallCount($listener, 'registerService', [
870
            ['EntityListener1', 'entity_listener1'],
871
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
872
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
873
            ['ParentEntityListener', 'children_entity_listener'],
874
        ], 4);
875
876
        $listener = $container->getDefinition('doctrine.orm.em2_entity_listener_resolver');
877
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener2', 'entity_listener2']);
878
879
        $attachListener = $container->getDefinition('doctrine.orm.em1_listeners.attach_entity_listeners');
880
        $this->assertDICDefinitionMethodCallAt(0, $attachListener, 'addEntityListener', ['My/Entity1', 'EntityListener1', 'postLoad']);
881
        $this->assertDICDefinitionMethodCallAt(1, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'loadClassMetadata', '__invoke']);
882
        $this->assertDICDefinitionMethodCallAt(2, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'postPersist']);
883
        $this->assertDICDefinitionMethodCallAt(3, $attachListener, 'addEntityListener', ['My/Entity3', 'ParentEntityListener', 'postLoad']);
884
885
        $attachListener = $container->getDefinition('doctrine.orm.em2_listeners.attach_entity_listeners');
886
        $this->assertDICDefinitionMethodCallOnce($attachListener, 'addEntityListener', ['My/Entity2', 'EntityListener2', 'preFlush', 'preFlushHandler']);
887
    }
888
889
    public function testAttachEntityListenersTwoConnections()
890
    {
891
        $container = $this->getContainer(['YamlBundle']);
892
        $loader    = new DoctrineExtension();
893
        $container->registerExtension($loader);
894
        $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'));
895
896
        $this->loadFromFile($container, 'orm_attach_entity_listeners_two_connections');
897
898
        $this->compileContainer($container);
899
900
        $defaultEventManager = $container->getDefinition('doctrine.dbal.default_connection.event_manager');
901
        $this->assertDICDefinitionNoMethodCall($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
902
        $this->assertDICDefinitionMethodCallOnce($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
903
904
        $foobarEventManager = $container->getDefinition('doctrine.dbal.foobar_connection.event_manager');
905
        $this->assertDICDefinitionNoMethodCall($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
906
        $this->assertDICDefinitionMethodCallOnce($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
907
    }
908
909
    public function testAttachLazyEntityListener()
910
    {
911
        $container = $this->getContainer([]);
912
        $loader    = new DoctrineExtension();
913
        $container->registerExtension($loader);
914
        $container->addCompilerPass(new EntityListenerPass());
915
916
        $this->loadFromFile($container, 'orm_attach_lazy_entity_listener');
917
918
        $this->compileContainer($container);
919
920
        $resolver1 = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
921
        $this->assertDICDefinitionMethodCallAt(0, $resolver1, 'registerService', ['EntityListener1', 'entity_listener1']);
922
        $this->assertDICDefinitionMethodCallAt(1, $resolver1, 'register', [new Reference('entity_listener3')]);
923
        $this->assertDICDefinitionMethodCallAt(2, $resolver1, 'registerService', ['EntityListener4', 'entity_listener4']);
924
925
        $serviceLocatorReference = $resolver1->getArgument(0);
926
        $this->assertInstanceOf(Reference::class, $serviceLocatorReference);
927
        $serviceLocatorDefinition = $container->getDefinition((string) $serviceLocatorReference);
928
        $this->assertSame(ServiceLocator::class, $serviceLocatorDefinition->getClass());
929
        $serviceLocatorMap = $serviceLocatorDefinition->getArgument(0);
930
        $this->assertSame(['entity_listener1', 'entity_listener4'], array_keys($serviceLocatorMap));
931
932
        $resolver2 = $container->findDefinition('custom_entity_listener_resolver');
933
        $this->assertDICDefinitionMethodCallOnce($resolver2, 'registerService', ['EntityListener2', 'entity_listener2']);
934
    }
935
936
    public function testAttachLazyEntityListenerForCustomResolver()
937
    {
938
        $container = $this->getContainer([]);
939
        $loader    = new DoctrineExtension();
940
        $container->registerExtension($loader);
941
        $container->addCompilerPass(new EntityListenerPass());
942
943
        $this->loadFromFile($container, 'orm_entity_listener_custom_resolver');
944
945
        $this->compileContainer($container);
946
947
        $resolver = $container->getDefinition('custom_entity_listener_resolver');
948
        $this->assertTrue($resolver->isPublic());
949
        $this->assertEmpty($resolver->getArguments(), 'We must not change the arguments for custom services.');
950
        $this->assertDICDefinitionMethodCallOnce($resolver, 'registerService', ['EntityListener', 'entity_listener']);
951
        $this->assertTrue($container->getDefinition('entity_listener')->isPublic());
952
    }
953
954
    /**
955
     * @expectedException \InvalidArgumentException
956
     * @expectedExceptionMessage EntityListenerServiceResolver
957
     */
958 View Code Duplication
    public function testLazyEntityListenerResolverWithoutCorrectInterface()
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...
959
    {
960
        $container = $this->getContainer([]);
961
        $loader    = new DoctrineExtension();
962
        $container->registerExtension($loader);
963
        $container->addCompilerPass(new EntityListenerPass());
964
965
        $this->loadFromFile($container, 'orm_entity_listener_lazy_resolver_without_interface');
966
967
        $this->compileContainer($container);
968
    }
969
970
    public function testPrivateLazyEntityListener()
971
    {
972
        $container = $this->getContainer([]);
973
        $loader    = new DoctrineExtension();
974
        $container->registerExtension($loader);
975
        $container->addCompilerPass(new EntityListenerPass());
976
977
        $this->loadFromFile($container, 'orm_entity_listener_lazy_private');
978
979
        $this->compileContainer($container);
980
981
        $this->assertTrue($container->getDefinition('doctrine.orm.em1_entity_listener_resolver')->isPublic());
982
    }
983
984
    /**
985
     * @expectedException \InvalidArgumentException
986
     * @expectedExceptionMessageRegExp /The service ".*" must not be abstract as this entity listener is lazy-loaded/
987
     */
988 View Code Duplication
    public function testAbstractLazyEntityListener()
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...
989
    {
990
        $container = $this->getContainer([]);
991
        $loader    = new DoctrineExtension();
992
        $container->registerExtension($loader);
993
        $container->addCompilerPass(new EntityListenerPass());
994
995
        $this->loadFromFile($container, 'orm_entity_listener_lazy_abstract');
996
997
        $this->compileContainer($container);
998
    }
999
1000
    public function testRepositoryFactory()
1001
    {
1002
        $container = $this->loadContainer('orm_repository_factory');
1003
1004
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
1005
        $this->assertDICDefinitionMethodCallOnce($definition, 'setRepositoryFactory', ['repository_factory']);
1006
    }
1007
1008
    private function loadContainer($fixture, array $bundles = ['YamlBundle'], CompilerPassInterface $compilerPass = null)
1009
    {
1010
        $container = $this->getContainer($bundles);
1011
        $container->registerExtension(new DoctrineExtension());
1012
1013
        $this->loadFromFile($container, $fixture);
1014
1015
        if ($compilerPass !== null) {
1016
            $container->addCompilerPass($compilerPass);
1017
        }
1018
1019
        $this->compileContainer($container);
1020
1021
        return $container;
1022
    }
1023
1024
    private function getContainer(array $bundles)
1025
    {
1026
        $map = [];
1027
        foreach ($bundles as $bundle) {
1028
            require_once __DIR__ . '/Fixtures/Bundles/' . $bundle . '/' . $bundle . '.php';
1029
1030
            $map[$bundle] = 'Fixtures\\Bundles\\' . $bundle . '\\' . $bundle;
1031
        }
1032
1033
        $container = new ContainerBuilder(new ParameterBag([
1034
            'kernel.name' => 'app',
1035
            'kernel.debug' => false,
1036
            'kernel.bundles' => $map,
1037
            'kernel.cache_dir' => sys_get_temp_dir(),
1038
            'kernel.environment' => 'test',
1039
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
1040
            'kernel.project_dir' => __DIR__ . '/../../', // src dir
1041
            'kernel.bundles_metadata' => [],
1042
            'container.build_id' => uniqid(),
1043
        ]));
1044
1045
        // Register dummy cache services so we don't have to load the FrameworkExtension
1046
        $container->setDefinition('cache.system', (new Definition(ArrayAdapter::class))->setPublic(true));
1047
        $container->setDefinition('cache.app', (new Definition(ArrayAdapter::class))->setPublic(true));
1048
1049
        return $container;
1050
    }
1051
1052
    /**
1053
     * Assertion on the Class of a DIC Service Definition.
1054
     *
1055
     * @param string $expectedClass
1056
     */
1057
    private function assertDICDefinitionClass(Definition $definition, $expectedClass)
1058
    {
1059
        $this->assertEquals($expectedClass, $definition->getClass(), 'Expected Class of the DIC Container Service Definition is wrong.');
1060
    }
1061
1062
    private function assertDICConstructorArguments(Definition $definition, $args)
1063
    {
1064
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
1065
    }
1066
1067 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...
1068
    {
1069
        $calls = $definition->getMethodCalls();
1070
        if (! isset($calls[$pos][0])) {
1071
            $this->fail(sprintf('Method call at position %s not found!', $pos));
1072
1073
            return;
1074
        }
1075
1076
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
1077
1078
        if ($params === null) {
1079
            return;
1080
        }
1081
1082
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1083
    }
1084
1085
    /**
1086
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
1087
     *
1088
     * @param string $methodName
1089
     * @param array  $params
0 ignored issues
show
Documentation introduced by
Should the type for parameter $params not be null|array?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1090
     */
1091 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...
1092
    {
1093
        $calls  = $definition->getMethodCalls();
1094
        $called = false;
1095
        foreach ($calls as $call) {
1096
            if ($call[0] !== $methodName) {
1097
                continue;
1098
            }
1099
1100
            if ($called) {
1101
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
1102
            } else {
1103
                $called = true;
1104
                if ($params !== null) {
1105
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1106
                }
1107
            }
1108
        }
1109
        if ($called) {
1110
            return;
1111
        }
1112
1113
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
1114
    }
1115
1116
    private function assertDICDefinitionMethodCallCount(Definition $definition, $methodName, array $params = [], $nbCalls = 1)
1117
    {
1118
        $calls  = $definition->getMethodCalls();
1119
        $called = 0;
1120
        foreach ($calls as $call) {
1121
            if ($call[0] !== $methodName) {
1122
                continue;
1123
            }
1124
1125
            if ($called > $nbCalls) {
1126
                break;
1127
            }
1128
1129
            if (isset($params[$called])) {
1130
                $this->assertEquals($params[$called], $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1131
            }
1132
            $called++;
1133
        }
1134
1135
        $this->assertEquals($nbCalls, $called, sprintf('The method "%s" should be called %d times', $methodName, $nbCalls));
1136
    }
1137
1138
    /**
1139
     * Assertion for the DI Container, check if the given definition does not contain a method call with the given parameters.
1140
     *
1141
     * @param string $methodName
1142
     * @param array  $params
0 ignored issues
show
Documentation introduced by
Should the type for parameter $params not be null|array?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1143
     */
1144
    private function assertDICDefinitionNoMethodCall(Definition $definition, $methodName, array $params = null)
1145
    {
1146
        $calls = $definition->getMethodCalls();
1147
        foreach ($calls as $call) {
1148
            if ($call[0] !== $methodName) {
1149
                continue;
1150
            }
1151
1152
            if ($params !== null) {
1153
                $this->assertNotEquals($params, $call[1], "Method '" . $methodName . "' is not expected to be called with the given parameters.");
1154
            } else {
1155
                $this->fail("Method '" . $methodName . "' is not expected to be called");
1156
            }
1157
        }
1158
    }
1159
1160
    private function compileContainer(ContainerBuilder $container)
1161
    {
1162
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
1163
        $container->getCompilerPassConfig()->setRemovingPasses([]);
1164
        $container->compile();
1165
    }
1166
}
1167
1168
class DummySchemaAssetsFilter
1169
{
1170
    /** @var string */
1171
    private $tableToIgnore;
1172
1173
    public function __construct(string $tableToIgnore)
1174
    {
1175
        $this->tableToIgnore = $tableToIgnore;
1176
    }
1177
1178
    public function __invoke($assetName) : bool
1179
    {
1180
        if ($assetName instanceof AbstractAsset) {
1181
            $assetName = $assetName->getName();
1182
        }
1183
1184
        return $assetName !== $this->tableToIgnore;
1185
    }
1186
}
1187