Failed Conditions
Pull Request — 3.0.x (#3934)
by Sergei
114:39 queued 49:35
created

tests/ConnectionTest.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Doctrine\DBAL\Tests;
4
5
use Doctrine\Common\Cache\Cache;
6
use Doctrine\Common\EventManager;
7
use Doctrine\DBAL\Cache\ArrayStatement;
8
use Doctrine\DBAL\Cache\QueryCacheProfile;
9
use Doctrine\DBAL\Configuration;
10
use Doctrine\DBAL\Connection;
11
use Doctrine\DBAL\ConnectionException;
12
use Doctrine\DBAL\DBALException;
13
use Doctrine\DBAL\Driver;
14
use Doctrine\DBAL\Driver\Connection as DriverConnection;
15
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
16
use Doctrine\DBAL\Driver\Statement;
17
use Doctrine\DBAL\DriverManager;
18
use Doctrine\DBAL\Events;
19
use Doctrine\DBAL\Exception\InvalidArgumentException;
20
use Doctrine\DBAL\FetchMode;
21
use Doctrine\DBAL\Logging\DebugStack;
22
use Doctrine\DBAL\Logging\EchoSQLLogger;
0 ignored issues
show
The type Doctrine\DBAL\Logging\EchoSQLLogger was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Doctrine\DBAL\ParameterType;
24
use Doctrine\DBAL\Platforms\AbstractPlatform;
25
use Doctrine\DBAL\VersionAwarePlatformDriver;
26
use Exception;
27
use PHPUnit\Framework\MockObject\MockObject;
28
use PHPUnit\Framework\TestCase;
29
use stdClass;
30
31
/**
32
 * @requires extension pdo_mysql
33
 */
34
class ConnectionTest extends TestCase
35
{
36
    /** @var Connection */
37
    private $connection;
38
39
    /** @var string[] */
40
    protected $params = [
41
        'driver' => 'pdo_mysql',
42
        'host' => 'localhost',
43
        'user' => 'root',
44
        'password' => 'password',
45
        'port' => '1234',
46
    ];
47
48
    protected function setUp() : void
49
    {
50
        $this->connection = DriverManager::getConnection($this->params);
51
    }
52
53
    /**
54
     * @return Connection|MockObject
55
     */
56
    private function getExecuteUpdateMockConnection()
57
    {
58
        $driverMock = $this->createMock(Driver::class);
59
60
        $driverMock->expects($this->any())
61
            ->method('connect')
62
            ->will($this->returnValue(
63
                $this->createMock(DriverConnection::class)
64
            ));
65
66
        $platform = $this->getMockForAbstractClass(AbstractPlatform::class);
67
68
        return $this->getMockBuilder(Connection::class)
69
            ->onlyMethods(['executeUpdate'])
70
            ->setConstructorArgs([['platform' => $platform], $driverMock])
71
            ->getMock();
72
    }
73
74
    public function testIsConnected() : void
75
    {
76
        self::assertFalse($this->connection->isConnected());
77
    }
78
79
    public function testNoTransactionActiveByDefault() : void
80
    {
81
        self::assertFalse($this->connection->isTransactionActive());
82
    }
83
84
    public function testCommitWithNoActiveTransactionThrowsException() : void
85
    {
86
        $this->expectException(ConnectionException::class);
87
        $this->connection->commit();
88
    }
89
90
    public function testRollbackWithNoActiveTransactionThrowsException() : void
91
    {
92
        $this->expectException(ConnectionException::class);
93
        $this->connection->rollBack();
94
    }
95
96
    public function testSetRollbackOnlyNoActiveTransactionThrowsException() : void
97
    {
98
        $this->expectException(ConnectionException::class);
99
        $this->connection->setRollbackOnly();
100
    }
101
102
    public function testIsRollbackOnlyNoActiveTransactionThrowsException() : void
103
    {
104
        $this->expectException(ConnectionException::class);
105
        $this->connection->isRollbackOnly();
106
    }
107
108
    public function testGetConfiguration() : void
109
    {
110
        $config = $this->connection->getConfiguration();
111
112
        self::assertInstanceOf(Configuration::class, $config);
113
    }
114
115
    public function testGetHost() : void
116
    {
117
        self::assertEquals('localhost', $this->connection->getHost());
118
    }
119
120
    public function testGetPort() : void
121
    {
122
        self::assertEquals('1234', $this->connection->getPort());
123
    }
124
125
    public function testGetUsername() : void
126
    {
127
        self::assertEquals('root', $this->connection->getUsername());
128
    }
129
130
    public function testGetPassword() : void
131
    {
132
        self::assertEquals('password', $this->connection->getPassword());
133
    }
134
135
    public function testGetDriver() : void
136
    {
137
        self::assertInstanceOf(\Doctrine\DBAL\Driver\PDOMySql\Driver::class, $this->connection->getDriver());
138
    }
139
140
    public function testGetEventManager() : void
141
    {
142
        self::assertInstanceOf(EventManager::class, $this->connection->getEventManager());
143
    }
144
145
    public function testConnectDispatchEvent() : void
146
    {
147
        $listenerMock = $this->getMockBuilder($this->getMockClass('ConnectDispatchEventListener'))
148
            ->addMethods(['postConnect'])
149
            ->getMock();
150
        $listenerMock->expects($this->once())->method('postConnect');
151
152
        $eventManager = new EventManager();
153
        $eventManager->addEventListener([Events::postConnect], $listenerMock);
154
155
        $driverMock = $this->createMock(Driver::class);
156
        $driverMock->expects($this->at(0))
157
                   ->method('connect');
158
159
        $conn = new Connection([], $driverMock, new Configuration(), $eventManager);
160
        $conn->connect();
161
    }
162
163
    public function testEventManagerPassedToPlatform() : void
164
    {
165
        $eventManager = new EventManager();
166
167
        /** @var AbstractPlatform|MockObject $driver */
168
        $platform = $this->createMock(AbstractPlatform::class);
169
        $platform->expects($this->once())
170
            ->method('setEventManager')
171
            ->with($eventManager);
172
173
        /** @var Driver|MockObject $driver */
174
        $driver = $this->createMock(Driver::class);
175
        $driver->expects($this->any())
176
            ->method('getDatabasePlatform')
177
            ->willReturn($platform);
178
179
        $connection = new Connection($this->params, $driver, null, $eventManager);
180
        $connection->getDatabasePlatform();
181
    }
182
183
    /**
184
     * @requires extension pdo_sqlite
185
     * @dataProvider getQueryMethods
186
     */
187
    public function testDriverExceptionIsWrapped(string $method) : void
188
    {
189
        $this->expectException(DBALException::class);
190
        $this->expectExceptionMessage("An exception occurred while executing 'MUUHAAAAHAAAA':\n\nSQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
191
192
        $connection = DriverManager::getConnection([
193
            'driver' => 'pdo_sqlite',
194
            'memory' => true,
195
        ]);
196
197
        $connection->$method('MUUHAAAAHAAAA');
198
    }
199
200
    /**
201
     * @return array<int, array<int, mixed>>
202
     */
203
    public static function getQueryMethods() : iterable
204
    {
205
        return [
206
            ['exec'],
207
            ['query'],
208
            ['executeQuery'],
209
            ['executeUpdate'],
210
            ['prepare'],
211
        ];
212
    }
213
214
    /**
215
     * Pretty dumb test, however we want to check that the DebugStack correctly implements the interface.
216
     *
217
     * @group DBAL-11
218
     */
219
    public function testDebugSQLStack() : void
220
    {
221
        $logger = new DebugStack();
222
        $this->connection->getConfiguration()->setSQLLogger($logger);
223
        self::assertSame($logger, $this->connection->getConfiguration()->getSQLLogger());
224
    }
225
226
    /**
227
     * @group DBAL-81
228
     */
229
    public function testIsAutoCommit() : void
230
    {
231
        self::assertTrue($this->connection->isAutoCommit());
232
    }
233
234
    /**
235
     * @group DBAL-81
236
     */
237
    public function testSetAutoCommit() : void
238
    {
239
        $this->connection->setAutoCommit(false);
240
        self::assertFalse($this->connection->isAutoCommit());
241
        $this->connection->setAutoCommit(0);
242
        self::assertFalse($this->connection->isAutoCommit());
243
    }
244
245
    /**
246
     * @group DBAL-81
247
     */
248
    public function testConnectStartsTransactionInNoAutoCommitMode() : void
249
    {
250
        $driverMock = $this->createMock(Driver::class);
251
        $driverMock->expects($this->any())
252
            ->method('connect')
253
            ->will($this->returnValue(
254
                $this->createMock(DriverConnection::class)
255
            ));
256
        $conn = new Connection([], $driverMock);
257
258
        $conn->setAutoCommit(false);
259
260
        self::assertFalse($conn->isTransactionActive());
261
262
        $conn->connect();
263
264
        self::assertTrue($conn->isTransactionActive());
265
    }
266
267
    /**
268
     * @group DBAL-81
269
     */
270
    public function testCommitStartsTransactionInNoAutoCommitMode() : void
271
    {
272
        $driverMock = $this->createMock(Driver::class);
273
        $driverMock->expects($this->any())
274
            ->method('connect')
275
            ->will($this->returnValue(
276
                $this->createMock(DriverConnection::class)
277
            ));
278
        $conn = new Connection([], $driverMock);
279
280
        $conn->setAutoCommit(false);
281
        $conn->connect();
282
        $conn->commit();
283
284
        self::assertTrue($conn->isTransactionActive());
285
    }
286
287
    /**
288
     * @dataProvider resultProvider
289
     */
290
    public function testCommitReturn(bool $expectedResult) : void
291
    {
292
        $driverConnection = $this->createMock(DriverConnection::class);
293
        $driverConnection->expects($this->once())
294
            ->method('commit')->willReturn($expectedResult);
295
296
        $driverMock = $this->createMock(Driver::class);
297
        $driverMock->expects($this->any())
298
            ->method('connect')
299
            ->will($this->returnValue($driverConnection));
300
301
        $conn = new Connection([], $driverMock);
302
303
        $conn->connect();
304
        $conn->beginTransaction();
305
306
        self::assertSame($expectedResult, $conn->commit());
307
    }
308
309
    /**
310
     * @return bool[][]
311
     */
312
    public function resultProvider() : array
313
    {
314
        return [[true], [false]];
315
    }
316
317
    /**
318
     * @group DBAL-81
319
     */
320
    public function testRollBackStartsTransactionInNoAutoCommitMode() : void
321
    {
322
        $driverMock = $this->createMock(Driver::class);
323
        $driverMock->expects($this->any())
324
            ->method('connect')
325
            ->will($this->returnValue(
326
                $this->createMock(DriverConnection::class)
327
            ));
328
        $conn = new Connection([], $driverMock);
329
330
        $conn->setAutoCommit(false);
331
        $conn->connect();
332
        $conn->rollBack();
333
334
        self::assertTrue($conn->isTransactionActive());
335
    }
336
337
    /**
338
     * @group DBAL-81
339
     */
340
    public function testSwitchingAutoCommitModeCommitsAllCurrentTransactions() : void
341
    {
342
        $driverMock = $this->createMock(Driver::class);
343
        $driverMock->expects($this->any())
344
            ->method('connect')
345
            ->will($this->returnValue(
346
                $this->createMock(DriverConnection::class)
347
            ));
348
        $conn = new Connection([], $driverMock);
349
350
        $conn->connect();
351
        $conn->beginTransaction();
352
        $conn->beginTransaction();
353
        $conn->setAutoCommit(false);
354
355
        self::assertSame(1, $conn->getTransactionNestingLevel());
356
357
        $conn->beginTransaction();
358
        $conn->beginTransaction();
359
        $conn->setAutoCommit(true);
360
361
        self::assertFalse($conn->isTransactionActive());
362
    }
363
364
    public function testEmptyInsert() : void
365
    {
366
        $conn = $this->getExecuteUpdateMockConnection();
367
368
        $conn->expects($this->once())
369
            ->method('executeUpdate')
370
            ->with('INSERT INTO footable () VALUES ()');
371
372
        $conn->insert('footable', []);
373
    }
374
375
    /**
376
     * @group DBAL-2511
377
     */
378
    public function testUpdateWithDifferentColumnsInDataAndIdentifiers() : void
379
    {
380
        $conn = $this->getExecuteUpdateMockConnection();
381
382
        $conn->expects($this->once())
383
            ->method('executeUpdate')
384
            ->with(
385
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND name = ?',
386
                [
387
                    'some text',
388
                    true,
389
                    1,
390
                    'foo',
391
                ],
392
                [
393
                    'string',
394
                    'boolean',
395
                    'integer',
396
                    'string',
397
                ]
398
            );
399
400
        $conn->update(
401
            'TestTable',
402
            [
403
                'text' => 'some text',
404
                'is_edited' => true,
405
            ],
406
            [
407
                'id' => 1,
408
                'name' => 'foo',
409
            ],
410
            [
411
                'text' => 'string',
412
                'is_edited' => 'boolean',
413
                'id' => 'integer',
414
                'name' => 'string',
415
            ]
416
        );
417
    }
418
419
    /**
420
     * @group DBAL-2511
421
     */
422
    public function testUpdateWithSameColumnInDataAndIdentifiers() : void
423
    {
424
        $conn = $this->getExecuteUpdateMockConnection();
425
426
        $conn->expects($this->once())
427
            ->method('executeUpdate')
428
            ->with(
429
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND is_edited = ?',
430
                [
431
                    'some text',
432
                    true,
433
                    1,
434
                    false,
435
                ],
436
                [
437
                    'string',
438
                    'boolean',
439
                    'integer',
440
                    'boolean',
441
                ]
442
            );
443
444
        $conn->update(
445
            'TestTable',
446
            [
447
                'text' => 'some text',
448
                'is_edited' => true,
449
            ],
450
            [
451
                'id' => 1,
452
                'is_edited' => false,
453
            ],
454
            [
455
                'text' => 'string',
456
                'is_edited' => 'boolean',
457
                'id' => 'integer',
458
            ]
459
        );
460
    }
461
462
    /**
463
     * @group DBAL-2688
464
     */
465
    public function testUpdateWithIsNull() : void
466
    {
467
        $conn = $this->getExecuteUpdateMockConnection();
468
469
        $conn->expects($this->once())
470
            ->method('executeUpdate')
471
            ->with(
472
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id IS NULL AND name = ?',
473
                [
474
                    'some text',
475
                    null,
476
                    'foo',
477
                ],
478
                [
479
                    'string',
480
                    'boolean',
481
                    'string',
482
                ]
483
            );
484
485
        $conn->update(
486
            'TestTable',
487
            [
488
                'text' => 'some text',
489
                'is_edited' => null,
490
            ],
491
            [
492
                'id' => null,
493
                'name' => 'foo',
494
            ],
495
            [
496
                'text' => 'string',
497
                'is_edited' => 'boolean',
498
                'id' => 'integer',
499
                'name' => 'string',
500
            ]
501
        );
502
    }
503
504
    /**
505
     * @group DBAL-2688
506
     */
507
    public function testDeleteWithIsNull() : void
508
    {
509
        $conn = $this->getExecuteUpdateMockConnection();
510
511
        $conn->expects($this->once())
512
            ->method('executeUpdate')
513
            ->with(
514
                'DELETE FROM TestTable WHERE id IS NULL AND name = ?',
515
                ['foo'],
516
                ['string']
517
            );
518
519
        $conn->delete(
520
            'TestTable',
521
            [
522
                'id' => null,
523
                'name' => 'foo',
524
            ],
525
            [
526
                'id' => 'integer',
527
                'name' => 'string',
528
            ]
529
        );
530
    }
531
532
    public function testFetchAssoc() : void
533
    {
534
        $statement = 'SELECT * FROM foo WHERE bar = ?';
535
        $params    = [666];
536
        $types     = [ParameterType::INTEGER];
537
        $result    = [];
538
539
        $driverMock = $this->createMock(Driver::class);
540
541
        $driverMock->expects($this->any())
542
            ->method('connect')
543
            ->will($this->returnValue(
544
                $this->createMock(DriverConnection::class)
545
            ));
546
547
        $driverStatementMock = $this->createMock(Statement::class);
548
549
        $driverStatementMock->expects($this->once())
550
            ->method('fetch')
551
            ->with(FetchMode::ASSOCIATIVE)
552
            ->will($this->returnValue($result));
553
554
        /** @var Connection|MockObject $conn */
555
        $conn = $this->getMockBuilder(Connection::class)
556
            ->onlyMethods(['executeQuery'])
557
            ->setConstructorArgs([[], $driverMock])
558
            ->getMock();
559
560
        $conn->expects($this->once())
561
            ->method('executeQuery')
562
            ->with($statement, $params, $types)
563
            ->will($this->returnValue($driverStatementMock));
564
565
        self::assertSame($result, $conn->fetchAssoc($statement, $params, $types));
566
    }
567
568
    public function testFetchArray() : void
569
    {
570
        $statement = 'SELECT * FROM foo WHERE bar = ?';
571
        $params    = [666];
572
        $types     = [ParameterType::INTEGER];
573
        $result    = [];
574
575
        $driverMock = $this->createMock(Driver::class);
576
577
        $driverMock->expects($this->any())
578
            ->method('connect')
579
            ->will($this->returnValue(
580
                $this->createMock(DriverConnection::class)
581
            ));
582
583
        $driverStatementMock = $this->createMock(Statement::class);
584
585
        $driverStatementMock->expects($this->once())
586
            ->method('fetch')
587
            ->with(FetchMode::NUMERIC)
588
            ->will($this->returnValue($result));
589
590
        /** @var Connection|MockObject $conn */
591
        $conn = $this->getMockBuilder(Connection::class)
592
            ->onlyMethods(['executeQuery'])
593
            ->setConstructorArgs([[], $driverMock])
594
            ->getMock();
595
596
        $conn->expects($this->once())
597
            ->method('executeQuery')
598
            ->with($statement, $params, $types)
599
            ->will($this->returnValue($driverStatementMock));
600
601
        self::assertSame($result, $conn->fetchArray($statement, $params, $types));
602
    }
603
604
    public function testFetchColumn() : void
605
    {
606
        $statement = 'SELECT * FROM foo WHERE bar = ?';
607
        $params    = [666];
608
        $types     = [ParameterType::INTEGER];
609
        $column    = 0;
610
        $result    = [];
611
612
        $driverMock = $this->createMock(Driver::class);
613
614
        $driverMock->expects($this->any())
615
            ->method('connect')
616
            ->will($this->returnValue(
617
                $this->createMock(DriverConnection::class)
618
            ));
619
620
        $driverStatementMock = $this->createMock(Statement::class);
621
622
        $driverStatementMock->expects($this->once())
623
            ->method('fetchColumn')
624
            ->with($column)
625
            ->will($this->returnValue($result));
626
627
        /** @var Connection|MockObject $conn */
628
        $conn = $this->getMockBuilder(Connection::class)
629
            ->onlyMethods(['executeQuery'])
630
            ->setConstructorArgs([[], $driverMock])
631
            ->getMock();
632
633
        $conn->expects($this->once())
634
            ->method('executeQuery')
635
            ->with($statement, $params, $types)
636
            ->will($this->returnValue($driverStatementMock));
637
638
        self::assertSame($result, $conn->fetchColumn($statement, $params, $column, $types));
639
    }
640
641
    public function testFetchAll() : void
642
    {
643
        $statement = 'SELECT * FROM foo WHERE bar = ?';
644
        $params    = [666];
645
        $types     = [ParameterType::INTEGER];
646
        $result    = [];
647
648
        $driverMock = $this->createMock(Driver::class);
649
650
        $driverMock->expects($this->any())
651
            ->method('connect')
652
            ->will($this->returnValue(
653
                $this->createMock(DriverConnection::class)
654
            ));
655
656
        $driverStatementMock = $this->createMock(Statement::class);
657
658
        $driverStatementMock->expects($this->once())
659
            ->method('fetchAll')
660
            ->will($this->returnValue($result));
661
662
        /** @var Connection|MockObject $conn */
663
        $conn = $this->getMockBuilder(Connection::class)
664
            ->onlyMethods(['executeQuery'])
665
            ->setConstructorArgs([[], $driverMock])
666
            ->getMock();
667
668
        $conn->expects($this->once())
669
            ->method('executeQuery')
670
            ->with($statement, $params, $types)
671
            ->will($this->returnValue($driverStatementMock));
672
673
        self::assertSame($result, $conn->fetchAll($statement, $params, $types));
674
    }
675
676
    public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() : void
677
    {
678
        /** @var Driver $driver */
679
        $driver = $this->createMock(Driver::class);
680
        $conn   = new Connection([], $driver);
681
682
        $this->expectException(InvalidArgumentException::class);
683
        $conn->delete('kittens', []);
684
    }
685
686
    public function testCallConnectOnce() : void
687
    {
688
        /** @var Driver|MockObject $driver */
689
        $driver = $this->createMock(Driver::class);
690
        $driver->expects($this->once())
691
            ->method('connect');
692
693
        $platform = $this->createMock(AbstractPlatform::class);
694
695
        $conn = new Connection(['platform' => $platform], $driver);
696
        $conn->connect();
697
        $conn->connect();
698
    }
699
700
    /**
701
     * @group DBAL-1127
702
     */
703
    public function testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform() : void
704
    {
705
        /** @var VersionAwarePlatformDriver|MockObject $driverMock */
706
        $driverMock = $this->createMock(VersionAwarePlatformDriver::class);
707
708
        /** @var ServerInfoAwareConnection|MockObject $driverConnectionMock */
709
        $driverConnectionMock = $this->createMock(ServerInfoAwareConnection::class);
710
711
        /** @var AbstractPlatform|MockObject $platformMock */
712
        $platformMock = $this->getMockForAbstractClass(AbstractPlatform::class);
713
714
        $connection = new Connection([], $driverMock);
715
716
        $driverMock->expects($this->once())
717
            ->method('connect')
718
            ->will($this->returnValue($driverConnectionMock));
719
720
        $driverConnectionMock->expects($this->once())
721
            ->method('requiresQueryForServerVersion')
722
            ->will($this->returnValue(false));
723
724
        $driverConnectionMock->expects($this->once())
725
            ->method('getServerVersion')
726
            ->will($this->returnValue('6.6.6'));
727
728
        $driverMock->expects($this->once())
729
            ->method('createDatabasePlatformForVersion')
730
            ->with('6.6.6')
731
            ->will($this->returnValue($platformMock));
732
733
        self::assertSame($platformMock, $connection->getDatabasePlatform());
734
    }
735
736
    public function testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCacheQuery() : void
737
    {
738
        $resultCacheDriverMock = $this->createMock(Cache::class);
739
740
        $resultCacheDriverMock
741
            ->expects($this->atLeastOnce())
742
            ->method('fetch')
743
            ->with('cacheKey')
744
            ->will($this->returnValue(['realKey' => []]));
745
746
        $query  = 'SELECT * FROM foo WHERE bar = ?';
747
        $params = [666];
748
        $types  = [ParameterType::INTEGER];
749
750
        /** @var QueryCacheProfile|MockObject $queryCacheProfileMock */
751
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
752
753
        $queryCacheProfileMock
754
            ->expects($this->any())
755
            ->method('getResultCacheDriver')
756
            ->will($this->returnValue($resultCacheDriverMock));
757
758
        // This is our main expectation
759
        $queryCacheProfileMock
760
            ->expects($this->once())
761
            ->method('generateCacheKeys')
762
            ->with($query, $params, $types, $this->params)
763
            ->will($this->returnValue(['cacheKey', 'realKey']));
764
765
        /** @var Driver $driver */
766
        $driver = $this->createMock(Driver::class);
767
768
        self::assertInstanceOf(
769
            ArrayStatement::class,
770
            (new Connection($this->params, $driver))->executeCacheQuery($query, $params, $types, $queryCacheProfileMock)
771
        );
772
    }
773
774
    /**
775
     * @group #2821
776
     */
777
    public function testShouldNotPassPlatformInParamsToTheQueryCacheProfileInExecuteCacheQuery() : void
778
    {
779
        $resultCacheDriverMock = $this->createMock(Cache::class);
780
781
        $resultCacheDriverMock
782
            ->expects($this->atLeastOnce())
783
            ->method('fetch')
784
            ->with('cacheKey')
785
            ->will($this->returnValue(['realKey' => []]));
786
787
        /** @var QueryCacheProfile|MockObject $queryCacheProfileMock */
788
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
789
790
        $queryCacheProfileMock
791
            ->expects($this->any())
792
            ->method('getResultCacheDriver')
793
            ->will($this->returnValue($resultCacheDriverMock));
794
795
        $query = 'SELECT 1';
796
797
        $connectionParams = $this->params;
798
799
        $queryCacheProfileMock
800
            ->expects($this->once())
801
            ->method('generateCacheKeys')
802
            ->with($query, [], [], $connectionParams)
803
            ->will($this->returnValue(['cacheKey', 'realKey']));
804
805
        $connectionParams['platform'] = $this->createMock(AbstractPlatform::class);
806
807
        /** @var Driver $driver */
808
        $driver = $this->createMock(Driver::class);
809
810
        (new Connection($connectionParams, $driver))->executeCacheQuery($query, [], [], $queryCacheProfileMock);
811
    }
812
813
    /**
814
     * @group #2821
815
     */
816
    public function testThrowsExceptionWhenInValidPlatformSpecified() : void
817
    {
818
        $connectionParams             = $this->params;
819
        $connectionParams['platform'] = new stdClass();
820
821
        /** @var Driver $driver */
822
        $driver = $this->createMock(Driver::class);
823
824
        $this->expectException(DBALException::class);
825
826
        new Connection($connectionParams, $driver);
827
    }
828
829
    /**
830
     * @group DBAL-990
831
     */
832
    public function testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase() : void
833
    {
834
        /** @var VersionAwarePlatformDriver|MockObject $driverMock */
835
        $driverMock = $this->createMock(VersionAwarePlatformDriver::class);
836
837
        $connection        = new Connection(['dbname' => 'foo'], $driverMock);
838
        $originalException = new Exception('Original exception');
839
        $fallbackException = new Exception('Fallback exception');
840
841
        $driverMock->expects($this->at(0))
842
            ->method('connect')
843
            ->willThrowException($originalException);
844
845
        $driverMock->expects($this->at(1))
846
            ->method('connect')
847
            ->willThrowException($fallbackException);
848
849
        $this->expectExceptionMessage($originalException->getMessage());
850
851
        $connection->getDatabasePlatform();
852
    }
853
854
    /**
855
     * @group #3194
856
     */
857
    public function testExecuteCacheQueryStripsPlatformFromConnectionParamsBeforeGeneratingCacheKeys() : void
858
    {
859
        /** @var Driver|MockObject $driver */
860
        $driver = $this->createMock(Driver::class);
861
862
        /** @var AbstractPlatform|MockObject $platform */
863
        $platform = $this->createMock(AbstractPlatform::class);
864
865
        /** @var QueryCacheProfile|MockObject $queryCacheProfile */
866
        $queryCacheProfile = $this->createMock(QueryCacheProfile::class);
867
868
        /** @var Cache|MockObject $resultCacheDriver */
869
        $resultCacheDriver = $this->createMock(Cache::class);
870
871
        $queryCacheProfile
872
            ->expects($this->any())
873
            ->method('getResultCacheDriver')
874
            ->will($this->returnValue($resultCacheDriver));
875
876
        $resultCacheDriver
877
            ->expects($this->atLeastOnce())
878
            ->method('fetch')
879
            ->with('cacheKey')
880
            ->will($this->returnValue(['realKey' => []]));
881
882
        $query = 'SELECT 1';
883
884
        $params = [
885
            'dbname' => 'foo',
886
            'platform' => $platform,
887
        ];
888
889
        $paramsWithoutPlatform = $params;
890
        unset($paramsWithoutPlatform['platform']);
891
892
        $queryCacheProfile
893
            ->expects($this->once())
894
            ->method('generateCacheKeys')
895
            ->with($query, [], [], $paramsWithoutPlatform)
896
            ->will($this->returnValue(['cacheKey', 'realKey']));
897
898
        $connection = new Connection($params, $driver);
899
900
        self::assertSame($params, $connection->getParams());
901
902
        $connection->executeCacheQuery($query, [], [], $queryCacheProfile);
903
    }
904
}
905