testAttachEntityListeners()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 72

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 72
rs 8.6109
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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, string $file) : void;
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() : void
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
        $this->assertSame(['asin' => ['callback' => 'asin', 'numArgs' => 1]], $config['driverOptions']['userDefinedFunctions']);
49
        $this->assertSame('foo', $config['driverOptions']['arbitraryValue']);
50
51
        // doctrine.dbal.oci8_connection
52
        $config = $container->getDefinition('doctrine.dbal.oci_connection')->getArgument(0);
53
        $this->assertSame('oci8', $config['driver']);
54
        $this->assertSame('oracle_db', $config['dbname']);
55
        $this->assertSame('oracle_user', $config['user']);
56
        $this->assertSame('oracle_s3cr3t', $config['password']);
57
        $this->assertSame('oracle_service', $config['servicename']);
58
        $this->assertTrue($config['service']);
59
        $this->assertTrue($config['pooled']);
60
        $this->assertSame('utf8', $config['charset']);
61
62
        // doctrine.dbal.ibmdb2_connection
63
        $config = $container->getDefinition('doctrine.dbal.ibmdb2_connection')->getArgument(0);
64
        $this->assertSame('ibm_db2', $config['driver']);
65
        $this->assertSame('ibmdb2_db', $config['dbname']);
66
        $this->assertSame('ibmdb2_user', $config['user']);
67
        $this->assertSame('ibmdb2_s3cr3t', $config['password']);
68
        $this->assertSame('TCPIP', $config['protocol']);
69
70
        // doctrine.dbal.pgsql_connection
71
        $config = $container->getDefinition('doctrine.dbal.pgsql_connection')->getArgument(0);
72
        $this->assertSame('pdo_pgsql', $config['driver']);
73
        $this->assertSame('pgsql_schema', $config['dbname']);
74
        $this->assertSame('pgsql_user', $config['user']);
75
        $this->assertSame('pgsql_s3cr3t', $config['password']);
76
        $this->assertSame('pgsql_db', $config['default_dbname']);
77
        $this->assertSame('require', $config['sslmode']);
78
        $this->assertSame('postgresql-ca.pem', $config['sslrootcert']);
79
        $this->assertSame('postgresql-cert.pem', $config['sslcert']);
80
        $this->assertSame('postgresql-key.pem', $config['sslkey']);
81
        $this->assertSame('postgresql.crl', $config['sslcrl']);
82
        $this->assertSame('utf8', $config['charset']);
83
84
        // doctrine.dbal.sqlanywhere_connection
85
        $config = $container->getDefinition('doctrine.dbal.sqlanywhere_connection')->getArgument(0);
86
        $this->assertSame('sqlanywhere', $config['driver']);
87
        $this->assertSame('localhost', $config['host']);
88
        $this->assertSame(2683, $config['port']);
89
        $this->assertSame('sqlanywhere_server', $config['server']);
90
        $this->assertSame('sqlanywhere_db', $config['dbname']);
91
        $this->assertSame('sqlanywhere_user', $config['user']);
92
        $this->assertSame('sqlanywhere_s3cr3t', $config['password']);
93
        $this->assertTrue($config['persistent']);
94
        $this->assertSame('utf8', $config['charset']);
95
    }
96
97
    public function testDbalLoadFromXmlSingleConnections() : void
98
    {
99
        $container = $this->loadContainer('dbal_service_single_connection');
100
101
        // doctrine.dbal.mysql_connection
102
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
103
104
        $this->assertEquals('mysql_s3cr3t', $config['password']);
105
        $this->assertEquals('mysql_user', $config['user']);
106
        $this->assertEquals('mysql_db', $config['dbname']);
107
        $this->assertEquals('/path/to/mysqld.sock', $config['unix_socket']);
108
        $this->assertEquals('5.6.20', $config['serverVersion']);
109
    }
110
111
    public function testDbalLoadSingleMasterSlaveConnection() : void
112
    {
113
        $container = $this->loadContainer('dbal_service_single_master_slave_connection');
114
115
        // doctrine.dbal.mysql_connection
116
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
117
118
        $this->assertEquals('Doctrine\\DBAL\\Connections\\MasterSlaveConnection', $param['wrapperClass']);
119
        $this->assertTrue($param['keepSlave']);
120
        $this->assertEquals(
121
            [
122
                'user' => 'mysql_user',
123
                'password' => 'mysql_s3cr3t',
124
                'port' => null,
125
                'dbname' => 'mysql_db',
126
                'host' => 'localhost',
127
                'unix_socket' => '/path/to/mysqld.sock',
128
            ],
129
            $param['master']
130
        );
131
        $this->assertEquals(
132
            [
133
                'user' => 'slave_user',
134
                'password' => 'slave_s3cr3t',
135
                'port' => null,
136
                'dbname' => 'slave_db',
137
                'host' => 'localhost',
138
                'unix_socket' => '/path/to/mysqld_slave.sock',
139
            ],
140
            $param['slaves']['slave1']
141
        );
142
        $this->assertEquals(['engine' => 'InnoDB'], $param['defaultTableOptions']);
143
    }
144
145
    public function testDbalLoadPoolShardingConnection() : void
146
    {
147
        $container = $this->loadContainer('dbal_service_pool_sharding_connection');
148
149
        // doctrine.dbal.mysql_connection
150
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
151
152
        $this->assertEquals('Doctrine\\DBAL\\Sharding\\PoolingShardConnection', $param['wrapperClass']);
153
        $this->assertEquals(new Reference('foo.shard_choser'), $param['shardChoser']);
154
        $this->assertEquals(
155
            [
156
                'user' => 'mysql_user',
157
                'password' => 'mysql_s3cr3t',
158
                'port' => null,
159
                'dbname' => 'mysql_db',
160
                'host' => 'localhost',
161
                'unix_socket' => '/path/to/mysqld.sock',
162
            ],
163
            $param['global']
164
        );
165
        $this->assertEquals(
166
            [
167
                'user' => 'shard_user',
168
                'password' => 'shard_s3cr3t',
169
                'port' => null,
170
                'dbname' => 'shard_db',
171
                'host' => 'localhost',
172
                'unix_socket' => '/path/to/mysqld_shard.sock',
173
                'id' => 1,
174
            ],
175
            $param['shards'][0]
176
        );
177
        $this->assertEquals(['engine' => 'InnoDB'], $param['defaultTableOptions']);
178
    }
179
180
    public function testDbalLoadSavepointsForNestedTransactions() : void
181
    {
182
        $container = $this->loadContainer('dbal_savepoints');
183
184
        $calls = $container->getDefinition('doctrine.dbal.savepoints_connection')->getMethodCalls();
185
        $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...
186
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
187
        $this->assertTrue($calls[0][1][0]);
188
189
        $calls = $container->getDefinition('doctrine.dbal.nosavepoints_connection')->getMethodCalls();
190
        $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...
191
192
        $calls = $container->getDefinition('doctrine.dbal.notset_connection')->getMethodCalls();
193
        $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...
194
    }
195
196
    public function testLoadSimpleSingleConnection() : void
197
    {
198
        $container = $this->loadContainer('orm_service_simple_single_entity_manager');
199
200
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
201
202
        $this->assertDICConstructorArguments($definition, [
203
            [
204
                'dbname' => 'db',
205
                'host' => 'localhost',
206
                'port' => null,
207
                'user' => 'root',
208
                'password' => null,
209
                'driver' => 'pdo_mysql',
210
                'driverOptions' => [],
211
                'defaultTableOptions' => [],
212
            ],
213
            new Reference('doctrine.dbal.default_connection.configuration'),
214
            new Reference('doctrine.dbal.default_connection.event_manager'),
215
            [],
216
        ]);
217
218
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
219
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
220
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
221
222
        $this->assertDICConstructorArguments($definition, [
223
            new Reference('doctrine.dbal.default_connection'),
224
            new Reference('doctrine.orm.default_configuration'),
225
        ]);
226
    }
227
228
    /**
229
     * The PDO driver doesn't require a database name to be to set when connecting to a database server
230
     */
231
    public function testLoadSimpleSingleConnectionWithoutDbName() : void
232
    {
233
        $container = $this->loadContainer('orm_service_simple_single_entity_manager_without_dbname');
234
235
        /** @var Definition $definition */
236
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
237
238
        $this->assertDICConstructorArguments($definition, [
239
            [
240
                'host' => 'localhost',
241
                'port' => null,
242
                'user' => 'root',
243
                'password' => null,
244
                'driver' => 'pdo_mysql',
245
                'driverOptions' => [],
246
                'defaultTableOptions' => [],
247
            ],
248
            new Reference('doctrine.dbal.default_connection.configuration'),
249
            new Reference('doctrine.dbal.default_connection.event_manager'),
250
            [],
251
        ]);
252
253
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
254
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
255
        $factory = $definition->getFactory();
256
257
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $factory[0]);
258
        $this->assertEquals('create', $factory[1]);
259
260
        $this->assertDICConstructorArguments($definition, [
261
            new Reference('doctrine.dbal.default_connection'),
262
            new Reference('doctrine.orm.default_configuration'),
263
        ]);
264
    }
265
266
    public function testLoadSingleConnection() : void
267
    {
268
        $container = $this->loadContainer('orm_service_single_entity_manager');
269
270
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
271
272
        $this->assertDICConstructorArguments($definition, [
273
            [
274
                'host' => 'localhost',
275
                'driver' => 'pdo_sqlite',
276
                'driverOptions' => [],
277
                'user' => 'sqlite_user',
278
                'port' => null,
279
                'password' => 'sqlite_s3cr3t',
280
                'dbname' => 'sqlite_db',
281
                'memory' => true,
282
                'defaultTableOptions' => [],
283
            ],
284
            new Reference('doctrine.dbal.default_connection.configuration'),
285
            new Reference('doctrine.dbal.default_connection.event_manager'),
286
            [],
287
        ]);
288
289
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
290
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
291
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
292
293
        $this->assertDICConstructorArguments($definition, [
294
            new Reference('doctrine.dbal.default_connection'),
295
            new Reference('doctrine.orm.default_configuration'),
296
        ]);
297
298
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
299
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setDefaultRepositoryClassName', ['Acme\Doctrine\Repository']);
300
    }
301
302
    public function testLoadMultipleConnections() : void
303
    {
304
        $container = $this->loadContainer('orm_service_multiple_entity_managers');
305
306
        $definition = $container->getDefinition('doctrine.dbal.conn1_connection');
307
308
        $args = $definition->getArguments();
309
        $this->assertEquals('pdo_sqlite', $args[0]['driver']);
310
        $this->assertEquals('localhost', $args[0]['host']);
311
        $this->assertEquals('sqlite_user', $args[0]['user']);
312
        $this->assertEquals('doctrine.dbal.conn1_connection.configuration', (string) $args[1]);
313
        $this->assertEquals('doctrine.dbal.conn1_connection.event_manager', (string) $args[2]);
314
315
        $this->assertEquals('doctrine.orm.em2_entity_manager', (string) $container->getAlias('doctrine.orm.entity_manager'));
316
317
        $definition = $container->getDefinition('doctrine.orm.em1_entity_manager');
318
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
319
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
320
321
        $arguments = $definition->getArguments();
322
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
323
        $this->assertEquals('doctrine.dbal.conn1_connection', (string) $arguments[0]);
324
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
325
        $this->assertEquals('doctrine.orm.em1_configuration', (string) $arguments[1]);
326
327
        $definition = $container->getDefinition('doctrine.dbal.conn2_connection');
328
329
        $args = $definition->getArguments();
330
        $this->assertEquals('pdo_sqlite', $args[0]['driver']);
331
        $this->assertEquals('localhost', $args[0]['host']);
332
        $this->assertEquals('sqlite_user', $args[0]['user']);
333
        $this->assertEquals('doctrine.dbal.conn2_connection.configuration', (string) $args[1]);
334
        $this->assertEquals('doctrine.dbal.conn2_connection.event_manager', (string) $args[2]);
335
336
        $definition = $container->getDefinition('doctrine.orm.em2_entity_manager');
337
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
338
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
339
340
        $arguments = $definition->getArguments();
341
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
342
        $this->assertEquals('doctrine.dbal.conn2_connection', (string) $arguments[0]);
343
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
344
        $this->assertEquals('doctrine.orm.em2_configuration', (string) $arguments[1]);
345
346
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
347
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
348
349
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_query_cache'));
350
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
351
        $arguments = $definition->getArguments();
352
        $this->assertInstanceOf(Reference::class, $arguments[0]);
353
        $this->assertEquals('cache.doctrine.orm.em1.query', (string) $arguments[0]);
354
355
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_result_cache'));
356
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
357
        $arguments = $definition->getArguments();
358
        $this->assertInstanceOf(Reference::class, $arguments[0]);
359
        $this->assertEquals('cache.doctrine.orm.em1.result', (string) $arguments[0]);
360
    }
361
362
    public function testLoadLogging() : void
363
    {
364
        $container = $this->loadContainer('dbal_logging');
365
366
        $definition = $container->getDefinition('doctrine.dbal.log_connection.configuration');
367
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger')]);
368
369
        $definition = $container->getDefinition('doctrine.dbal.profile_connection.configuration');
370
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.profiling.profile')]);
371
372
        $definition = $container->getDefinition('doctrine.dbal.profile_with_backtrace_connection.configuration');
373
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.backtrace.profile_with_backtrace')]);
374
375
        $definition = $container->getDefinition('doctrine.dbal.backtrace_without_profile_connection.configuration');
376
        $this->assertDICDefinitionNoMethodCall($definition, 'setSQLLogger');
377
378
        $definition = $container->getDefinition('doctrine.dbal.both_connection.configuration');
379
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.chain.both')]);
380
    }
381
382
    public function testEntityManagerMetadataCacheDriverConfiguration() : void
383
    {
384
        $container = $this->loadContainer('orm_service_multiple_entity_managers');
385
386
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
387
        $this->assertDICDefinitionClass($definition, DoctrineProvider::class);
388
389
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em2_metadata_cache'));
390
        $this->assertDICDefinitionClass($definition, DoctrineProvider::class);
391
    }
392
393
    public function testDependencyInjectionImportsOverrideDefaults() : void
394
    {
395
        $container = $this->loadContainer('orm_imports');
396
397
        $cacheDefinition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
398
        $this->assertEquals(DoctrineProvider::class, $cacheDefinition->getClass());
399
400
        $configDefinition = $container->getDefinition('doctrine.orm.default_configuration');
401
        $this->assertDICDefinitionMethodCallOnce($configDefinition, 'setAutoGenerateProxyClasses', ['%doctrine.orm.auto_generate_proxy_classes%']);
402
    }
403
404
    public function testSingleEntityManagerMultipleMappingBundleDefinitions() : void
405
    {
406
        $container = $this->loadContainer('orm_single_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
407
408
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
409
410
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
411
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
412
            'Fixtures\Bundles\AnnotationsBundle\Entity',
413
        ]);
414
415
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
416
            new Reference('doctrine.orm.default_yml_metadata_driver'),
417
            'Fixtures\Bundles\YamlBundle\Entity',
418
        ]);
419
420
        $this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', [
421
            new Reference('doctrine.orm.default_xml_metadata_driver'),
422
            'Fixtures\Bundles\XmlBundle',
423
        ]);
424
425
        $annDef = $container->getDefinition('doctrine.orm.default_annotation_metadata_driver');
426
        $this->assertDICConstructorArguments($annDef, [
427
            new Reference('doctrine.orm.metadata.annotation_reader'),
428
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
429
        ]);
430
431
        $ymlDef = $container->getDefinition('doctrine.orm.default_yml_metadata_driver');
432
        $this->assertDICConstructorArguments($ymlDef, [
433
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
434
        ]);
435
436
        $xmlDef = $container->getDefinition('doctrine.orm.default_xml_metadata_driver');
437
        $this->assertDICConstructorArguments($xmlDef, [
438
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
439
        ]);
440
    }
441
442
    public function testMultipleEntityManagersMappingBundleDefinitions() : void
443
    {
444
        $container = $this->loadContainer('orm_multiple_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
445
446
        $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.');
447
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
448
449
        $def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver');
450
        $def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver');
451
452
        $this->assertDICDefinitionMethodCallAt(0, $def1, 'addDriver', [
453
            new Reference('doctrine.orm.em1_annotation_metadata_driver'),
454
            'Fixtures\Bundles\AnnotationsBundle\Entity',
455
        ]);
456
457
        $this->assertDICDefinitionMethodCallAt(0, $def2, 'addDriver', [
458
            new Reference('doctrine.orm.em2_yml_metadata_driver'),
459
            'Fixtures\Bundles\YamlBundle\Entity',
460
        ]);
461
462
        $this->assertDICDefinitionMethodCallAt(1, $def2, 'addDriver', [
463
            new Reference('doctrine.orm.em2_xml_metadata_driver'),
464
            'Fixtures\Bundles\XmlBundle',
465
        ]);
466
467
        $annDef = $container->getDefinition('doctrine.orm.em1_annotation_metadata_driver');
468
        $this->assertDICConstructorArguments($annDef, [
469
            new Reference('doctrine.orm.metadata.annotation_reader'),
470
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
471
        ]);
472
473
        $ymlDef = $container->getDefinition('doctrine.orm.em2_yml_metadata_driver');
474
        $this->assertDICConstructorArguments($ymlDef, [
475
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
476
        ]);
477
478
        $xmlDef = $container->getDefinition('doctrine.orm.em2_xml_metadata_driver');
479
        $this->assertDICConstructorArguments($xmlDef, [
480
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
481
        ]);
482
    }
483
484
    public function testSingleEntityManagerDefaultTableOptions() : void
485
    {
486
        $container = $this->loadContainer('orm_single_em_default_table_options', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
487
488
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
489
490
        $this->assertArrayHasKey('defaultTableOptions', $param);
491
492
        $defaults = $param['defaultTableOptions'];
493
494
        $this->assertArrayHasKey('charset', $defaults);
495
        $this->assertArrayHasKey('collate', $defaults);
496
        $this->assertArrayHasKey('engine', $defaults);
497
498
        $this->assertEquals('utf8mb4', $defaults['charset']);
499
        $this->assertEquals('utf8mb4_unicode_ci', $defaults['collate']);
500
        $this->assertEquals('InnoDB', $defaults['engine']);
501
    }
502
503
    public function testSetTypes() : void
504
    {
505
        $container = $this->loadContainer('dbal_types');
506
507
        $this->assertEquals(
508
            ['test' => ['class' => TestType::class]],
509
            $container->getParameter('doctrine.dbal.connection_factory.types')
510
        );
511
        $this->assertEquals('%doctrine.dbal.connection_factory.types%', $container->getDefinition('doctrine.dbal.connection_factory')->getArgument(0));
512
    }
513
514
    public function testSetCustomFunctions() : void
515
    {
516
        $container = $this->loadContainer('orm_functions');
517
518
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
519
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
520
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomNumericFunction', ['test_numeric', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction']);
521
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomDatetimeFunction', ['test_datetime', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction']);
522
    }
523
524 View Code Duplication
    public function testSetNamingStrategy() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
525
    {
526
        $container = $this->loadContainer('orm_namingstrategy');
527
528
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
529
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
530
531
        $this->assertDICDefinitionMethodCallOnce($def1, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.default')]);
532
        $this->assertDICDefinitionMethodCallOnce($def2, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.underscore')]);
533
    }
534
535 View Code Duplication
    public function testSetQuoteStrategy() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
536
    {
537
        $container = $this->loadContainer('orm_quotestrategy');
538
539
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
540
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
541
542
        $this->assertDICDefinitionMethodCallOnce($def1, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.default')]);
543
        $this->assertDICDefinitionMethodCallOnce($def2, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.ansi')]);
544
    }
545
546
    public function testSecondLevelCache() : void
547
    {
548
        $container = $this->loadContainer('orm_second_level_cache');
549
550
        $this->assertTrue($container->has('doctrine.orm.default_configuration'));
551
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.cache_configuration'));
552
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region_cache_driver'));
553
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.regions_configuration'));
554
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.default_cache_factory'));
555
556
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_chain'));
557
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_statistics'));
558
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger1'));
559
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger2'));
560
561
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_entity_region'));
562
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_service_region'));
563
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_query_region_filelock'));
564
565
        $slcFactoryDef       = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
566
        $myEntityRegionDef   = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_entity_region');
567
        $loggerChainDef      = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_chain');
568
        $loggerStatisticsDef = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_statistics');
569
        $myQueryRegionDef    = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_query_region_filelock');
570
        $cacheDriverDef      = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_second_level_cache.region_cache_driver'));
571
        $configDef           = $container->getDefinition('doctrine.orm.default_configuration');
572
        $myEntityRegionArgs  = $myEntityRegionDef->getArguments();
573
        $myQueryRegionArgs   = $myQueryRegionDef->getArguments();
574
        $slcFactoryArgs      = $slcFactoryDef->getArguments();
575
576
        $this->assertDICDefinitionClass($slcFactoryDef, '%doctrine.orm.second_level_cache.default_cache_factory.class%');
577
        $this->assertDICDefinitionClass($myQueryRegionDef, '%doctrine.orm.second_level_cache.filelock_region.class%');
578
        $this->assertDICDefinitionClass($myEntityRegionDef, '%doctrine.orm.second_level_cache.default_region.class%');
579
        $this->assertDICDefinitionClass($loggerChainDef, '%doctrine.orm.second_level_cache.logger_chain.class%');
580
        $this->assertDICDefinitionClass($loggerStatisticsDef, '%doctrine.orm.second_level_cache.logger_statistics.class%');
581
        $this->assertDICDefinitionClass($cacheDriverDef, DoctrineProvider::class);
582
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setSecondLevelCacheConfiguration');
583
        $this->assertDICDefinitionMethodCallCount($slcFactoryDef, 'setRegion', [], 3);
584
        $this->assertDICDefinitionMethodCallCount($loggerChainDef, 'setLogger', [], 3);
585
586
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[0]);
587
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[1]);
588
589
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myEntityRegionArgs[1]);
590
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myQueryRegionArgs[0]);
591
592
        $this->assertEquals('my_entity_region', $myEntityRegionArgs[0]);
593
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_entity_region_driver', $myEntityRegionArgs[1]);
594
        $this->assertEquals(600, $myEntityRegionArgs[2]);
595
596
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_query_region', $myQueryRegionArgs[0]);
597
        $this->assertContains('/doctrine/orm/slc/filelock', $myQueryRegionArgs[1]);
598
        $this->assertEquals(60, $myQueryRegionArgs[2]);
599
600
        $this->assertEquals('doctrine.orm.default_second_level_cache.regions_configuration', $slcFactoryArgs[0]);
601
        $this->assertEquals('doctrine.orm.default_second_level_cache.region_cache_driver', $slcFactoryArgs[1]);
602
    }
603
604
    public function testSingleEMSetCustomFunctions() : void
605
    {
606
        $container = $this->loadContainer('orm_single_em_dql_functions');
607
608
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
609
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
610
    }
611
612
    public function testAddCustomHydrationMode() : void
613
    {
614
        $container = $this->loadContainer('orm_hydration_mode');
615
616
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
617
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomHydrationMode', ['test_hydrator', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator']);
618
    }
619
620
    public function testAddFilter() : void
621
    {
622
        $container = $this->loadContainer('orm_filters');
623
624
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
625
        $args       = [
626
            ['soft_delete', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
627
            ['myFilter', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
628
        ];
629
        $this->assertDICDefinitionMethodCallCount($definition, 'addFilter', $args, 2);
630
631
        $definition = $container->getDefinition('doctrine.orm.default_manager_configurator');
632
        $this->assertDICConstructorArguments($definition, [['soft_delete', 'myFilter'], ['myFilter' => ['myParameter' => 'myValue', 'mySecondParameter' => 'mySecondValue']]]);
633
634
        // Let's create the instance to check the configurator work.
635
        /** @var EntityManager $entityManager */
636
        $entityManager = $container->get('doctrine.orm.entity_manager');
637
        $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...
638
    }
639
640
    public function testResolveTargetEntity() : void
641
    {
642
        $container = $this->loadContainer('orm_resolve_target_entity');
643
644
        $definition = $container->getDefinition('doctrine.orm.listeners.resolve_target_entity');
645
        $this->assertDICDefinitionMethodCallOnce($definition, 'addResolveTargetEntity', ['Symfony\Component\Security\Core\User\UserInterface', 'MyUserClass', []]);
646
647
        $tags = $definition->getTags();
648
        unset($tags['container.no_preload']);
649
        $this->assertEquals(['doctrine.event_subscriber' => [[]]], $tags);
650
    }
651
652
    public function testAttachEntityListeners() : void
653
    {
654
        $container = $this->loadContainer('orm_attach_entity_listener');
655
656
        $definition  = $container->getDefinition('doctrine.orm.default_listeners.attach_entity_listeners');
657
        $methodCalls = $definition->getMethodCalls();
658
659
        $this->assertDICDefinitionMethodCallCount($definition, 'addEntityListener', [], 6);
660
        $tags = $definition->getTags();
661
        unset($tags['container.no_preload']);
662
        $this->assertEquals(['doctrine.event_listener' => [ ['event' => 'loadClassMetadata'] ] ], $tags);
663
664
        $this->assertEquals($methodCalls[0], [
665
            'addEntityListener',
666
            [
667
                'ExternalBundles\Entities\FooEntity',
668
                'MyBundles\Listeners\FooEntityListener',
669
                'prePersist',
670
                null,
671
            ],
672
        ]);
673
674
        $this->assertEquals($methodCalls[1], [
675
            'addEntityListener',
676
            [
677
                'ExternalBundles\Entities\FooEntity',
678
                'MyBundles\Listeners\FooEntityListener',
679
                'postPersist',
680
                'postPersist',
681
            ],
682
        ]);
683
684
        $this->assertEquals($methodCalls[2], [
685
            'addEntityListener',
686
            [
687
                'ExternalBundles\Entities\FooEntity',
688
                'MyBundles\Listeners\FooEntityListener',
689
                'postLoad',
690
                'postLoadHandler',
691
            ],
692
        ]);
693
694
        $this->assertEquals($methodCalls[3], [
695
            'addEntityListener',
696
            [
697
                'ExternalBundles\Entities\BarEntity',
698
                'MyBundles\Listeners\BarEntityListener',
699
                'prePersist',
700
                'prePersist',
701
            ],
702
        ]);
703
704
        $this->assertEquals($methodCalls[4], [
705
            'addEntityListener',
706
            [
707
                'ExternalBundles\Entities\BarEntity',
708
                'MyBundles\Listeners\BarEntityListener',
709
                'prePersist',
710
                'prePersistHandler',
711
            ],
712
        ]);
713
714
        $this->assertEquals($methodCalls[5], [
715
            'addEntityListener',
716
            [
717
                'ExternalBundles\Entities\BarEntity',
718
                'MyBundles\Listeners\LogDeleteEntityListener',
719
                'postDelete',
720
                'postDelete',
721
            ],
722
        ]);
723
    }
724
725
    public function testDbalAutoCommit() : void
726
    {
727
        $container = $this->loadContainer('dbal_auto_commit');
728
729
        $definition = $container->getDefinition('doctrine.dbal.default_connection.configuration');
730
        $this->assertDICDefinitionMethodCallOnce($definition, 'setAutoCommit', [false]);
731
    }
732
733 View Code Duplication
    public function testDbalOracleConnectstring() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
734
    {
735
        $container = $this->loadContainer('dbal_oracle_connectstring');
736
737
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
738
        $this->assertSame('scott@sales-server:1521/sales.us.example.com', $config['connectstring']);
739
    }
740
741 View Code Duplication
    public function testDbalOracleInstancename() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
742
    {
743
        $container = $this->loadContainer('dbal_oracle_instancename');
744
745
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
746
        $this->assertSame('mySuperInstance', $config['instancename']);
747
    }
748
749
    public function testDbalSchemaFilterNewConfig() : void
750
    {
751
        $container = $this->getContainer([]);
752
        $loader    = new DoctrineExtension();
753
        $container->registerExtension($loader);
754
        $container->addCompilerPass(new WellKnownSchemaFilterPass());
755
        $container->addCompilerPass(new DbalSchemaFilterPass());
756
757
        // ignore table1 table on "default" connection
758
        $container->register('dummy_filter1', DummySchemaAssetsFilter::class)
759
            ->setArguments(['table1'])
760
            ->addTag('doctrine.dbal.schema_filter');
761
762
        // ignore table2 table on "connection2" connection
763
        $container->register('dummy_filter2', DummySchemaAssetsFilter::class)
764
            ->setArguments(['table2'])
765
            ->addTag('doctrine.dbal.schema_filter', ['connection' => 'connection2']);
766
767
        $this->loadFromFile($container, 'dbal_schema_filter');
768
769
        $assetNames               = ['table1', 'table2', 'table3', 't_ignored'];
770
        $expectedConnectionAssets = [
771
            // ignores table1 + schema_filter applies
772
            'connection1' => ['table2', 'table3'],
773
            // ignores table2, no schema_filter applies
774
            'connection2' => ['table1', 'table3', 't_ignored'],
775
            // connection3 has no ignores, handled separately
776
        ];
777
778
        $this->compileContainer($container);
779
780
        $getConfiguration = static function (string $connectionName) use ($container) : Configuration {
781
            return $container->get(sprintf('doctrine.dbal.%s_connection', $connectionName))->getConfiguration();
782
        };
783
784
        foreach ($expectedConnectionAssets as $connectionName => $expectedTables) {
785
            $connConfig = $getConfiguration($connectionName);
786
            $this->assertSame($expectedTables, array_values(array_filter($assetNames, $connConfig->getSchemaAssetsFilter())), sprintf('Filtering for connection "%s"', $connectionName));
787
        }
788
789
        $this->assertNull($connConfig = $getConfiguration('connection3')->getSchemaAssetsFilter());
790
    }
791
792
    public static function dataWellKnownSchemaFilterServices()
793
    {
794
        yield ['cache', 'cache_items'];
795
        yield ['lock', 'lock_keys'];
796
        yield ['messenger', 'messenger_messages'];
797
        yield ['messenger_legacy', 'messenger_messages'];
798
        yield ['session', 'sessions'];
799
    }
800
801
    /**
802
     * @dataProvider dataWellKnownSchemaFilterServices
803
     */
804
    public function testWellKnownSchemaFilterDefaultTables(string $fileName, string $tableName) : void
805
    {
806
        $container = $this->getContainer([]);
807
        $loader    = new DoctrineExtension();
808
        $container->registerExtension($loader);
809
        $container->addCompilerPass(new WellKnownSchemaFilterPass());
810
        $container->addCompilerPass(new DbalSchemaFilterPass());
811
812
        $this->loadFromFile($container, 'well_known_schema_filter_default_tables_' . $fileName);
813
814
        $this->compileContainer($container);
815
816
        $definition = $container->getDefinition('doctrine.dbal.well_known_schema_asset_filter');
817
818
        $this->assertSame([[$tableName]], $definition->getArguments());
819
        $this->assertSame([['connection' => 'connection1'], ['connection' => 'connection2'], ['connection' => 'connection3']], $definition->getTag('doctrine.dbal.schema_filter'));
820
821
        $definition = $container->getDefinition('doctrine.dbal.connection1_schema_asset_filter_manager');
822
823
        $this->assertEquals([new Reference('doctrine.dbal.well_known_schema_asset_filter'), new Reference('doctrine.dbal.connection1_regex_schema_filter')], $definition->getArgument(0));
824
825
        $filter = $container->get('well_known_filter');
826
827
        $this->assertFalse($filter($tableName));
828
        $this->assertTrue($filter('anything_else'));
829
    }
830
831
    public static function dataWellKnownSchemaOverriddenTablesFilterServices()
832
    {
833
        yield ['cache', 'app_cache'];
834
        yield ['lock', 'app_locks'];
835
        yield ['messenger', 'app_messages'];
836
        yield ['session', 'app_session'];
837
    }
838
839
    /**
840
     * @dataProvider dataWellKnownSchemaOverriddenTablesFilterServices
841
     */
842
    public function testWellKnownSchemaFilterOverriddenTables(string $fileName, string $tableName) : void
843
    {
844
        $container = $this->getContainer([]);
845
        $loader    = new DoctrineExtension();
846
        $container->registerExtension($loader);
847
        $container->addCompilerPass(new WellKnownSchemaFilterPass());
848
        $container->addCompilerPass(new DbalSchemaFilterPass());
849
850
        $this->loadFromFile($container, 'well_known_schema_filter_overridden_tables_' . $fileName);
851
852
        $this->compileContainer($container);
853
854
        $filter = $container->get('well_known_filter');
855
856
        $this->assertFalse($filter($tableName));
857
    }
858
859
    public function testEntityListenerResolver() : void
860
    {
861
        $container = $this->loadContainer('orm_entity_listener_resolver', ['YamlBundle'], new EntityListenerPass());
862
863
        $definition = $container->getDefinition('doctrine.orm.em1_configuration');
864
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em1_entity_listener_resolver')]);
865
866
        $definition = $container->getDefinition('doctrine.orm.em2_configuration');
867
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em2_entity_listener_resolver')]);
868
869
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
870
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener', 'entity_listener1']);
871
872
        $listener = $container->getDefinition('entity_listener_resolver');
873
        $this->assertDICDefinitionMethodCallOnce($listener, 'register', [new Reference('entity_listener2')]);
874
    }
875
876
    public function testAttachEntityListenerTag() : void
877
    {
878
        $container = $this->getContainer([]);
879
        $loader    = new DoctrineExtension();
880
        $container->registerExtension($loader);
881
        $container->addCompilerPass(new EntityListenerPass());
882
883
        $this->loadFromFile($container, 'orm_attach_entity_listener_tag');
884
885
        $this->compileContainer($container);
886
887
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
888
        $this->assertDICDefinitionMethodCallCount($listener, 'registerService', [
889
            ['ParentEntityListener', 'children_entity_listener'],
890
            ['EntityListener1', 'entity_listener1'],
891
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
892
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
893
        ], 4);
894
895
        $listener = $container->getDefinition('doctrine.orm.em2_entity_listener_resolver');
896
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener2', 'entity_listener2']);
897
898
        $attachListener = $container->getDefinition('doctrine.orm.em1_listeners.attach_entity_listeners');
899
        $this->assertDICDefinitionMethodCallAt(1, $attachListener, 'addEntityListener', ['My/Entity1', 'EntityListener1', 'postLoad']);
900
        $this->assertDICDefinitionMethodCallAt(2, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'loadClassMetadata', '__invoke']);
901
        $this->assertDICDefinitionMethodCallAt(3, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'postPersist']);
902
        $this->assertDICDefinitionMethodCallAt(0, $attachListener, 'addEntityListener', ['My/Entity3', 'ParentEntityListener', 'postLoad']);
903
904
        $attachListener = $container->getDefinition('doctrine.orm.em2_listeners.attach_entity_listeners');
905
        $this->assertDICDefinitionMethodCallOnce($attachListener, 'addEntityListener', ['My/Entity2', 'EntityListener2', 'preFlush', 'preFlushHandler']);
906
    }
907
908
    public function testAttachEntityListenersTwoConnections() : void
909
    {
910
        $container = $this->getContainer(['YamlBundle']);
911
        $loader    = new DoctrineExtension();
912
        $container->registerExtension($loader);
913
        $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'));
914
915
        $this->loadFromFile($container, 'orm_attach_entity_listeners_two_connections');
916
917
        $this->compileContainer($container);
918
919
        $defaultEventManager = $container->getDefinition('doctrine.dbal.default_connection.event_manager');
920
        $this->assertDICDefinitionNoMethodCall($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
921
        $this->assertDICDefinitionMethodCallOnce($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
922
923
        $foobarEventManager = $container->getDefinition('doctrine.dbal.foobar_connection.event_manager');
924
        $this->assertDICDefinitionNoMethodCall($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
925
        $this->assertDICDefinitionMethodCallOnce($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
926
    }
927
928
    public function testAttachLazyEntityListener() : void
929
    {
930
        $container = $this->getContainer([]);
931
        $loader    = new DoctrineExtension();
932
        $container->registerExtension($loader);
933
        $container->addCompilerPass(new EntityListenerPass());
934
935
        $this->loadFromFile($container, 'orm_attach_lazy_entity_listener');
936
937
        $this->compileContainer($container);
938
939
        $resolver1 = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
940
        $this->assertDICDefinitionMethodCallAt(0, $resolver1, 'registerService', ['EntityListener1', 'entity_listener1']);
941
        $this->assertDICDefinitionMethodCallAt(1, $resolver1, 'register', [new Reference('entity_listener3')]);
942
        $this->assertDICDefinitionMethodCallAt(2, $resolver1, 'registerService', ['EntityListener4', 'entity_listener4']);
943
944
        $serviceLocatorReference = $resolver1->getArgument(0);
945
        $this->assertInstanceOf(Reference::class, $serviceLocatorReference);
946
        $serviceLocatorDefinition = $container->getDefinition((string) $serviceLocatorReference);
947
        $this->assertSame(ServiceLocator::class, $serviceLocatorDefinition->getClass());
948
        $serviceLocatorMap = $serviceLocatorDefinition->getArgument(0);
949
        $this->assertSame(['entity_listener1', 'entity_listener4'], array_keys($serviceLocatorMap));
950
951
        $resolver2 = $container->findDefinition('custom_entity_listener_resolver');
952
        $this->assertDICDefinitionMethodCallOnce($resolver2, 'registerService', ['EntityListener2', 'entity_listener2']);
953
    }
954
955
    public function testAttachLazyEntityListenerForCustomResolver() : void
956
    {
957
        $container = $this->getContainer([]);
958
        $loader    = new DoctrineExtension();
959
        $container->registerExtension($loader);
960
        $container->addCompilerPass(new EntityListenerPass());
961
962
        $this->loadFromFile($container, 'orm_entity_listener_custom_resolver');
963
964
        $this->compileContainer($container);
965
966
        $resolver = $container->getDefinition('custom_entity_listener_resolver');
967
        $this->assertTrue($resolver->isPublic());
968
        $this->assertEmpty($resolver->getArguments(), 'We must not change the arguments for custom services.');
969
        $this->assertDICDefinitionMethodCallOnce($resolver, 'registerService', ['EntityListener', 'entity_listener']);
970
        $this->assertTrue($container->getDefinition('entity_listener')->isPublic());
971
    }
972
973
    /**
974
     * @expectedException \InvalidArgumentException
975
     * @expectedExceptionMessage EntityListenerServiceResolver
976
     */
977 View Code Duplication
    public function testLazyEntityListenerResolverWithoutCorrectInterface() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
978
    {
979
        $container = $this->getContainer([]);
980
        $loader    = new DoctrineExtension();
981
        $container->registerExtension($loader);
982
        $container->addCompilerPass(new EntityListenerPass());
983
984
        $this->loadFromFile($container, 'orm_entity_listener_lazy_resolver_without_interface');
985
986
        $this->compileContainer($container);
987
    }
988
989
    public function testPrivateLazyEntityListener() : void
990
    {
991
        $container = $this->getContainer([]);
992
        $loader    = new DoctrineExtension();
993
        $container->registerExtension($loader);
994
        $container->addCompilerPass(new EntityListenerPass());
995
996
        $this->loadFromFile($container, 'orm_entity_listener_lazy_private');
997
998
        $this->compileContainer($container);
999
1000
        $this->assertTrue($container->getDefinition('doctrine.orm.em1_entity_listener_resolver')->isPublic());
1001
    }
1002
1003
    /**
1004
     * @expectedException \InvalidArgumentException
1005
     * @expectedExceptionMessageRegExp /The service ".*" must not be abstract\./
1006
     */
1007 View Code Duplication
    public function testAbstractEntityListener() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1008
    {
1009
        $container = $this->getContainer([]);
1010
        $loader    = new DoctrineExtension();
1011
        $container->registerExtension($loader);
1012
        $container->addCompilerPass(new EntityListenerPass());
1013
1014
        $this->loadFromFile($container, 'orm_entity_listener_abstract');
1015
1016
        $this->compileContainer($container);
1017
    }
1018
1019
    public function testRepositoryFactory() : void
1020
    {
1021
        $container = $this->loadContainer('orm_repository_factory');
1022
1023
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
1024
        $this->assertDICDefinitionMethodCallOnce($definition, 'setRepositoryFactory', ['repository_factory']);
1025
    }
1026
1027
    private function loadContainer(
1028
        string $fixture,
1029
        array $bundles = ['YamlBundle'],
1030
        CompilerPassInterface $compilerPass = null
1031
    ) : ContainerBuilder {
1032
        $container = $this->getContainer($bundles);
1033
        $container->registerExtension(new DoctrineExtension());
1034
1035
        $this->loadFromFile($container, $fixture);
1036
1037
        if ($compilerPass !== null) {
1038
            $container->addCompilerPass($compilerPass);
1039
        }
1040
1041
        $this->compileContainer($container);
1042
1043
        return $container;
1044
    }
1045
1046
    private function getContainer(array $bundles) : ContainerBuilder
1047
    {
1048
        $map = [];
1049
        foreach ($bundles as $bundle) {
1050
            require_once __DIR__ . '/Fixtures/Bundles/' . $bundle . '/' . $bundle . '.php';
1051
1052
            $map[$bundle] = 'Fixtures\\Bundles\\' . $bundle . '\\' . $bundle;
1053
        }
1054
1055
        $container = new ContainerBuilder(new ParameterBag([
1056
            'kernel.name' => 'app',
1057
            'kernel.debug' => false,
1058
            'kernel.bundles' => $map,
1059
            'kernel.cache_dir' => sys_get_temp_dir(),
1060
            'kernel.environment' => 'test',
1061
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
1062
            'kernel.project_dir' => __DIR__ . '/../../', // src dir
1063
            'kernel.bundles_metadata' => [],
1064
            'container.build_id' => uniqid(),
1065
        ]));
1066
1067
        // Register dummy cache services so we don't have to load the FrameworkExtension
1068
        $container->setDefinition('cache.system', (new Definition(ArrayAdapter::class))->setPublic(true));
1069
        $container->setDefinition('cache.app', (new Definition(ArrayAdapter::class))->setPublic(true));
1070
1071
        return $container;
1072
    }
1073
1074
    /**
1075
     * Assertion on the Class of a DIC Service Definition.
1076
     */
1077
    private function assertDICDefinitionClass(Definition $definition, string $expectedClass) : void
1078
    {
1079
        $this->assertEquals($expectedClass, $definition->getClass(), 'Expected Class of the DIC Container Service Definition is wrong.');
1080
    }
1081
1082
    private function assertDICConstructorArguments(Definition $definition, array $args) : void
1083
    {
1084
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
1085
    }
1086
1087 View Code Duplication
    private function assertDICDefinitionMethodCallAt(
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...
1088
        int $pos,
1089
        Definition $definition,
1090
        string $methodName,
1091
        array $params = null
1092
    ) : void {
1093
        $calls = $definition->getMethodCalls();
1094
        if (! isset($calls[$pos][0])) {
1095
            $this->fail(sprintf('Method call at position %s not found!', $pos));
1096
1097
            return;
1098
        }
1099
1100
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
1101
1102
        if ($params === null) {
1103
            return;
1104
        }
1105
1106
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1107
    }
1108
1109
    /**
1110
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
1111
     */
1112 View Code Duplication
    private function assertDICDefinitionMethodCallOnce(
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...
1113
        Definition $definition,
1114
        string $methodName,
1115
        array $params = null
1116
    ) : void {
1117
        $calls  = $definition->getMethodCalls();
1118
        $called = false;
1119
        foreach ($calls as $call) {
1120
            if ($call[0] !== $methodName) {
1121
                continue;
1122
            }
1123
1124
            if ($called) {
1125
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
1126
            } else {
1127
                $called = true;
1128
                if ($params !== null) {
1129
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1130
                }
1131
            }
1132
        }
1133
        if ($called) {
1134
            return;
1135
        }
1136
1137
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
1138
    }
1139
1140
    private function assertDICDefinitionMethodCallCount(
1141
        Definition $definition,
1142
        string $methodName,
1143
        array $params = [],
1144
        int $nbCalls = 1
1145
    ) : void {
1146
        $calls  = $definition->getMethodCalls();
1147
        $called = 0;
1148
        foreach ($calls as $call) {
1149
            if ($call[0] !== $methodName) {
1150
                continue;
1151
            }
1152
1153
            if ($called > $nbCalls) {
1154
                break;
1155
            }
1156
1157
            if (isset($params[$called])) {
1158
                $this->assertEquals($params[$called], $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1159
            }
1160
            $called++;
1161
        }
1162
1163
        $this->assertEquals($nbCalls, $called, sprintf('The method "%s" should be called %d times', $methodName, $nbCalls));
1164
    }
1165
1166
    /**
1167
     * Assertion for the DI Container, check if the given definition does not contain a method call with the given parameters.
1168
     */
1169
    private function assertDICDefinitionNoMethodCall(
1170
        Definition $definition,
1171
        string $methodName,
1172
        array $params = null
1173
    ) : void {
1174
        $calls = $definition->getMethodCalls();
1175
        foreach ($calls as $call) {
1176
            if ($call[0] !== $methodName) {
1177
                continue;
1178
            }
1179
1180
            if ($params !== null) {
1181
                $this->assertNotEquals($params, $call[1], "Method '" . $methodName . "' is not expected to be called with the given parameters.");
1182
            } else {
1183
                $this->fail("Method '" . $methodName . "' is not expected to be called");
1184
            }
1185
        }
1186
    }
1187
1188
    private function compileContainer(ContainerBuilder $container) : void
1189
    {
1190
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
1191
        $container->getCompilerPassConfig()->setRemovingPasses([]);
1192
        $container->compile();
1193
    }
1194
}
1195
1196
class DummySchemaAssetsFilter
1197
{
1198
    /** @var string */
1199
    private $tableToIgnore;
1200
1201
    public function __construct(string $tableToIgnore)
1202
    {
1203
        $this->tableToIgnore = $tableToIgnore;
1204
    }
1205
1206
    public function __invoke($assetName) : bool
1207
    {
1208
        if ($assetName instanceof AbstractAsset) {
1209
            $assetName = $assetName->getName();
1210
        }
1211
1212
        return $assetName !== $this->tableToIgnore;
1213
    }
1214
}
1215