Completed
Push — master ( 52a24b...0631b2 )
by Alex
16s queued 13s
created

EntityManagerFactoryTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\LaminasDoctrine\Factory\Service\EntityManager;
6
7
use Arp\LaminasDoctrine\Config\EntityManagerConfigs;
8
use Arp\LaminasDoctrine\Factory\Service\EntityManager\EntityManagerFactory;
9
use Arp\LaminasDoctrine\Service\Configuration\ConfigurationManagerInterface;
10
use Arp\LaminasDoctrine\Service\Configuration\Exception\ConfigurationManagerException;
11
use Arp\LaminasDoctrine\Service\Connection\ConnectionManagerInterface;
12
use Arp\LaminasDoctrine\Service\Connection\Exception\ConnectionManagerException;
13
use Doctrine\Common\EventManager;
14
use Doctrine\DBAL\Connection;
15
use Doctrine\ORM\Configuration;
16
use Doctrine\ORM\EntityManagerInterface;
17
use Doctrine\ORM\Mapping\ClassMetadataFactory;
18
use Doctrine\ORM\Mapping\EntityListenerResolver;
19
use Doctrine\ORM\Repository\RepositoryFactory;
20
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
21
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
22
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
23
use Laminas\ServiceManager\ServiceLocatorInterface;
24
use Mockery\Adapter\Phpunit\MockeryTestCase;
25
use Mockery\MockInterface;
26
use Psr\Cache\CacheItemPoolInterface;
27
use Psr\Container\ContainerExceptionInterface;
28
use Psr\Container\ContainerInterface;
29
30
/**
31
 * @covers \Arp\LaminasDoctrine\Factory\Service\EntityManager\EntityManagerFactory
32
 */
33
final class EntityManagerFactoryTest extends MockeryTestCase
34
{
35
    /**
36
     * @var ContainerInterface&ServiceLocatorInterface&MockInterface
37
     */
38
    private ServiceLocatorInterface $container;
39
40
    /**
41
     * @var EntityManagerConfigs&MockInterface
42
     */
43
    private EntityManagerConfigs $entityManagerConfigs;
44
45
    /**
46
     * @var ConfigurationManagerInterface&MockInterface
47
     */
48
    private ConfigurationManagerInterface $configurationManager;
49
50
    /**
51
     * @var ConnectionManagerInterface&MockInterface
52
     */
53
    private ConnectionManagerInterface $connectionManager;
54
55
    public function setUp(): void
56
    {
57
        $this->container = \Mockery::mock(ServiceLocatorInterface::class);
58
        $this->entityManagerConfigs = \Mockery::mock(EntityManagerConfigs::class);
59
        $this->configurationManager = \Mockery::mock(ConfigurationManagerInterface::class);
60
        $this->connectionManager = \Mockery::mock(ConnectionManagerInterface::class);
61
    }
62
63
    public function testIsInvokable(): void
64
    {
65
        $this->assertIsCallable(new EntityManagerFactory());
66
    }
67
68
    /**
69
     * @throws ServiceNotFoundException
70
     * @throws ContainerExceptionInterface
71
     */
72
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheRequiredConfigurationConfigIsMissing(): void
73
    {
74
        $factory = new EntityManagerFactory();
75
76
        $serviceName = 'doctrine.entitymanager.orm_default';
77
        $emConfig = [
78
            'connection' => 'FooConnectionName',
79
            // missing 'configuration' key
80
        ];
81
82
        $this->container->shouldReceive('get')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not exist on Laminas\ServiceManager\ServiceLocatorInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

82
        $this->container->/** @scrutinizer ignore-call */ 
83
                          shouldReceive('get')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
83
            ->once()
84
            ->with(EntityManagerConfigs::class)
85
            ->andReturn($this->entityManagerConfigs);
86
87
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not exist on Arp\LaminasDoctrine\Config\EntityManagerConfigs. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

87
        $this->entityManagerConfigs->/** @scrutinizer ignore-call */ 
88
                                     shouldReceive('getEntityManagerConfig')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
88
            ->once()
89
            ->with($serviceName)
90
            ->andReturn($emConfig);
91
92
        $this->expectException(ServiceNotCreatedException::class);
93
        $this->expectExceptionMessage(
94
            sprintf(
95
                'The required \'configuration\' configuration option is missing for service \'%s\'',
96
                $serviceName
97
            )
98
        );
99
100
        $factory($this->container, $serviceName);
101
    }
102
103
    /**
104
     * @throws ServiceNotFoundException
105
     * @throws ContainerExceptionInterface
106
     */
107
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheRequiredConnectionConfigIsMissing(): void
108
    {
109
        $factory = new EntityManagerFactory();
110
111
        $serviceName = 'doctrine.entitymanager.orm_default';
112
        $emConfig = [
113
            'connection' => null,
114
            'configuration' => 'BarConfigurationName',
115
        ];
116
117
        $this->container->shouldReceive('get')
118
            ->once()
119
            ->with(EntityManagerConfigs::class)
120
            ->andReturn($this->entityManagerConfigs);
121
122
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
123
            ->once()
124
            ->with($serviceName)
125
            ->andReturn($emConfig);
126
127
        $this->expectException(ServiceNotCreatedException::class);
128
        $this->expectExceptionMessage(
129
            sprintf(
130
                'The required \'connection\' configuration option is missing for service \'%s\'',
131
                $serviceName
132
            )
133
        );
134
135
        $factory($this->container, $serviceName);
136
    }
137
138
    /**
139
     * @throws ServiceNotFoundException
140
     * @throws ContainerExceptionInterface
141
     */
142
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheConnectionServiceIsNotRegistered(): void
143
    {
144
        $factory = new EntityManagerFactory();
145
146
        /** @var Configuration&MockInterface $configuration */
147
        $configuration = \Mockery::mock(Configuration::class);
148
149
        $serviceName = 'doctrine.entitymanager.orm_default';
150
        $connectionName = 'foo';
151
        $emConfig = [
152
            'configuration' => $configuration,
153
            'connection' => $connectionName,
154
        ];
155
156
        $this->container->shouldReceive('get')
157
            ->once()
158
            ->with(EntityManagerConfigs::class)
159
            ->andReturn($this->entityManagerConfigs);
160
161
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
162
            ->once()
163
            ->with($serviceName)
164
            ->andReturn($emConfig);
165
166
        $this->container->shouldReceive('has')
167
            ->once()
168
            ->with(ConnectionManagerInterface::class)
169
            ->andReturn(true);
170
171
        $this->container->shouldReceive('get')
172
            ->once()
173
            ->with(ConnectionManagerInterface::class)
174
            ->andReturn($this->connectionManager);
175
176
        $this->connectionManager->shouldReceive('hasConnection')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not exist on Arp\LaminasDoctrine\Serv...nectionManagerInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

176
        $this->connectionManager->/** @scrutinizer ignore-call */ 
177
                                  shouldReceive('hasConnection')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
177
            ->once()
178
            ->with($emConfig['connection'])
179
            ->andReturn(false);
180
181
        $this->expectException(ServiceNotCreatedException::class);
182
        $this->expectExceptionMessage(
183
            sprintf(
184
                'Failed to load connection \'%s\' for service \'%s\': '
185
                . 'The connection has not been registered with the connection manager',
186
                $connectionName,
187
                $serviceName
188
            )
189
        );
190
191
        $factory($this->container, $serviceName);
192
    }
193
194
    /**
195
     * @throws ContainerExceptionInterface
196
     * @throws ServiceNotFoundException
197
     */
198
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheConnectionCannotBeCreated(): void
199
    {
200
        $factory = new EntityManagerFactory();
201
202
        /** @var Configuration&MockInterface $configuration */
203
        $configuration = \Mockery::mock(Configuration::class);
204
205
        $serviceName = 'doctrine.entitymanager.orm_default';
206
        $connectionName = 'foo';
207
        $emConfig = [
208
            'configuration' => $configuration,
209
            'connection' => $connectionName,
210
        ];
211
212
        $this->container->shouldReceive('get')
213
            ->once()
214
            ->with(EntityManagerConfigs::class)
215
            ->andReturn($this->entityManagerConfigs);
216
217
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
218
            ->once()
219
            ->with($serviceName)
220
            ->andReturn($emConfig);
221
222
        $this->container->shouldReceive('has')
223
            ->once()
224
            ->with(ConnectionManagerInterface::class)
225
            ->andReturn(true);
226
227
        $this->container->shouldReceive('get')
228
            ->once()
229
            ->with(ConnectionManagerInterface::class)
230
            ->andReturn($this->connectionManager);
231
232
        $this->connectionManager->shouldReceive('hasConnection')
233
            ->once()
234
            ->with($emConfig['connection'])
235
            ->andReturn(true);
236
237
        $exception = new ConnectionManagerException('This is a test exception message');
238
239
        $this->connectionManager->shouldReceive('getConnection')
240
            ->once()
241
            ->with($connectionName)
242
            ->andThrow($exception);
243
244
        $this->expectException(ServiceNotCreatedException::class);
245
        $this->expectExceptionMessage(
246
            sprintf('Failed to load connection \'%s\' for service \'%s\'', $connectionName, $serviceName),
247
        );
248
249
        $factory($this->container, $serviceName);
250
    }
251
252
    /**
253
     * @throws ServiceNotFoundException
254
     * @throws ContainerExceptionInterface
255
     */
256
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheConfigurationConfigIsMissing(): void
257
    {
258
        $factory = new EntityManagerFactory();
259
260
        $serviceName = 'doctrine.entitymanager.orm_default';
261
        $emConfig = [
262
            'connection' => \Mockery::mock(Connection::class),
263
        ];
264
265
        $this->container->shouldReceive('get')
266
            ->once()
267
            ->with(EntityManagerConfigs::class)
268
            ->andReturn($this->entityManagerConfigs);
269
270
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
271
            ->once()
272
            ->with($serviceName)
273
            ->andReturn($emConfig);
274
275
        $this->expectException(ServiceNotCreatedException::class);
276
        $this->expectExceptionMessage(
277
            sprintf(
278
                'The required \'configuration\' configuration option is missing for service \'%s\'',
279
                $serviceName
280
            )
281
        );
282
283
        $factory($this->container, $serviceName);
284
    }
285
286
    /**
287
     * Assert that a ServiceNotCreatedException is thrown from __invoke if the provided 'configuration'
288
     * string is not a valid configuration
289
     *
290
     * @throws ServiceNotFoundException
291
     * @throws ContainerExceptionInterface
292
     */
293
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheConfigurationServiceIsNotRegistered(): void
294
    {
295
        $factory = new EntityManagerFactory();
296
297
        $serviceName = 'doctrine.entitymanager.orm_default';
298
        $configurationName = 'FooConfiguration';
299
        $emConfig = [
300
            'connection' => \Mockery::mock(Connection::class),
301
            'configuration' => $configurationName,
302
        ];
303
304
        $this->container->shouldReceive('get')
305
            ->once()
306
            ->with(EntityManagerConfigs::class)
307
            ->andReturn($this->entityManagerConfigs);
308
309
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
310
            ->once()
311
            ->with($serviceName)
312
            ->andReturn($emConfig);
313
314
        $this->container->shouldReceive('has')
315
            ->once()
316
            ->with(ConfigurationManagerInterface::class)
317
            ->andReturn(true);
318
319
        $this->container->shouldReceive('get')
320
            ->once()
321
            ->with(ConfigurationManagerInterface::class)
322
            ->andReturn($this->configurationManager);
323
324
        $this->configurationManager->shouldReceive('hasConfiguration')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not exist on Arp\LaminasDoctrine\Serv...urationManagerInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

324
        $this->configurationManager->/** @scrutinizer ignore-call */ 
325
                                     shouldReceive('hasConfiguration')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
325
            ->once()
326
            ->with($configurationName)
327
            ->andReturn(false);
328
329
        $this->expectException(ServiceNotCreatedException::class);
330
        $this->expectExceptionMessage(
331
            sprintf(
332
                'Failed to load configuration \'%s\' for service \'%s\': '
333
                . 'The configuration has not been registered with the configuration manager',
334
                $configurationName,
335
                $serviceName
336
            )
337
        );
338
339
        $factory($this->container, $serviceName);
340
    }
341
342
    /**
343
     * @throws ContainerExceptionInterface
344
     * @throws ServiceNotFoundException
345
     */
346
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheConfigurationCannotBeCreated(): void
347
    {
348
        $factory = new EntityManagerFactory();
349
350
        $serviceName = 'doctrine.entitymanager.orm_default';
351
        $configurationName = 'FooConfiguration';
352
        $emConfig = [
353
            'connection' => \Mockery::mock(Connection::class),
354
            'configuration' => $configurationName,
355
        ];
356
357
        $this->container->shouldReceive('get')
358
            ->once()
359
            ->with(EntityManagerConfigs::class)
360
            ->andReturn($this->entityManagerConfigs);
361
362
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
363
            ->once()
364
            ->with($serviceName)
365
            ->andReturn($emConfig);
366
367
        $this->container->shouldReceive('has')
368
            ->once()
369
            ->with(ConfigurationManagerInterface::class)
370
            ->andReturn(true);
371
372
        $this->container->shouldReceive('get')
373
            ->once()
374
            ->with(ConfigurationManagerInterface::class)
375
            ->andReturn($this->configurationManager);
376
377
        $this->configurationManager->shouldReceive('hasConfiguration')
378
            ->once()
379
            ->with($configurationName)
380
            ->andReturn(true);
381
382
        $exception = new ConfigurationManagerException('This is a test exception message');
383
384
        $this->configurationManager->shouldReceive('getConfiguration')
385
            ->once()
386
            ->with($configurationName)
387
            ->andThrow($exception);
388
389
        $this->expectException(ServiceNotCreatedException::class);
390
        $this->expectExceptionMessage(
391
            sprintf('Failed to load configuration \'%s\' for service \'%s\'', $configurationName, $serviceName)
392
        );
393
394
        $factory($this->container, $serviceName);
395
    }
396
397
    /**
398
     * @throws ContainerExceptionInterface
399
     * @throws ServiceNotFoundException
400
     */
401
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheEventManagerIsInvalid(): void
402
    {
403
        $factory = new EntityManagerFactory();
404
405
        $serviceName = 'doctrine.entitymanager.orm_default';
406
407
        $eventManagerName = 'FooEventManager';
408
        $eventManager = new \stdClass();
409
410
        $emConfig = [
411
            'connection' => \Mockery::mock(Connection::class),
412
            'configuration' => \Mockery::mock(Configuration::class),
413
            'event_manager' => $eventManagerName,
414
        ];
415
416
        $this->container->shouldReceive('get')
417
            ->once()
418
            ->with(EntityManagerConfigs::class)
419
            ->andReturn($this->entityManagerConfigs);
420
421
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
422
            ->once()
423
            ->with($serviceName)
424
            ->andReturn($emConfig);
425
426
        $this->container->shouldReceive('has')
427
            ->once()
428
            ->with($eventManagerName)
429
            ->andReturn(true);
430
431
        $this->container->shouldReceive('get')
432
            ->once()
433
            ->with($eventManagerName)
434
            ->andReturn($eventManager);
435
436
        $this->expectException(ServiceNotCreatedException::class);
437
        $this->expectExceptionMessage(
438
            sprintf(
439
                'The event manager must be an object of type \'%s\'; \'%s\' provided for service \'%s\'',
440
                EventManager::class,
441
                get_class($eventManager),
442
                $serviceName,
443
            ),
444
        );
445
446
        $factory($this->container, $serviceName);
447
    }
448
449
    /**
450
     * @throws ContainerExceptionInterface
451
     * @throws ServiceNotFoundException
452
     * @throws ServiceNotCreatedException
453
     * @throws \InvalidArgumentException
454
     */
455
    public function testInvokeReturnsEventManager(): void
456
    {
457
        $factory = new EntityManagerFactory();
458
459
        $serviceName = 'doctrine.entitymanager.orm_default';
460
461
        /** @var Configuration&MockInterface $configuration */
462
        $configuration = \Mockery::mock(Configuration::class);
463
464
        /** @var MappingDriver&MockInterface $mappingDriver */
465
        $mappingDriver = \Mockery::mock(MappingDriver::class);
466
467
        $configuration->shouldReceive('getMetadataDriverImpl')
468
            ->once()
469
            ->andReturn($mappingDriver);
470
471
        $configuration->shouldReceive('getClassMetadataFactoryName')
472
            ->once()
473
            ->andReturn(ClassMetadataFactory::class);
474
475
        $configuration->shouldReceive('getMetadataCache')
476
            ->once()
477
            ->andReturn(\Mockery::mock(CacheItemPoolInterface::class));
478
479
        $configuration->shouldReceive('getRepositoryFactory')
480
            ->once()
481
            ->andReturn(\Mockery::mock(RepositoryFactory::class));
482
483
        $configuration->shouldReceive('getEntityListenerResolver')
484
            ->once()
485
            ->andReturn(\Mockery::mock(EntityListenerResolver::class));
486
487
        $configuration->shouldReceive('isLazyGhostObjectEnabled')
488
            ->once()
489
            ->andReturn(false);
490
491
        $configuration->shouldReceive('getProxyDir')->once()->andReturn('/foo/bar');
492
        $configuration->shouldReceive('getProxyNamespace')->once()->andReturn('Foo');
493
        $configuration->shouldReceive('getAutoGenerateProxyClasses')->once()->andReturn(false);
494
        $configuration->shouldReceive('isSecondLevelCacheEnabled')->times(2)->andReturn(false);
495
496
        $emConfig = [
497
            'connection' => \Mockery::mock(Connection::class),
498
            'configuration' => $configuration,
499
            'event_manager' => null,
500
        ];
501
502
        $this->container->shouldReceive('get')
503
            ->once()
504
            ->with(EntityManagerConfigs::class)
505
            ->andReturn($this->entityManagerConfigs);
506
507
        $this->entityManagerConfigs->shouldReceive('getEntityManagerConfig')
508
            ->once()
509
            ->with($serviceName)
510
            ->andReturn($emConfig);
511
512
        $this->assertInstanceOf(EntityManagerInterface::class, $factory($this->container, $serviceName));
513
    }
514
}
515