[BUGFIX] Add missing namespace parts
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Database / Schema / ConnectionMigratorTest.php
1 <?php
2 declare(strict_types=1);
3
4 namespace TYPO3\CMS\Core\Tests\Unit\Database;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use Doctrine\DBAL\Schema\Column;
20 use Doctrine\DBAL\Schema\SchemaDiff;
21 use Doctrine\DBAL\Schema\Table;
22 use TYPO3\CMS\Core\Database\Connection;
23 use TYPO3\CMS\Core\Database\Schema\ConnectionMigrator;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * Tests for ConnectionMigrator
28 */
29 class ConnectionMigratorTest extends \TYPO3\Components\TestingFramework\Core\Unit\UnitTestCase
30 {
31 /**
32 * @var array
33 */
34 protected $tableAndFieldMaxNameLengthsPerDbPlatform = [
35 'default' => [
36 'tables' => 10,
37 'columns' => 10,
38 ],
39 'dbplatform_type1' => [
40 'tables' => 15,
41 'columns' => 15,
42 ],
43 'dbplatform_type2' => 'dbplatform_type1'
44 ];
45
46 /**
47 * Utility method to quickly create a 'ConnectionMigratorMock' instance for
48 * a specific database platform.
49 *
50 * @param string $databasePlatformName
51 * @return \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
52 */
53 private function getConnectionMigratorMock($databasePlatformName='default')
54 {
55 $platformMock = $this->getMockBuilder(\Doctrine\DBAL\Platforms\AbstractPlatform::class)->disableOriginalConstructor()->getMock();
56 $platformMock->method('getName')->willReturn($databasePlatformName);
57
58 $connectionMock = $this->getMockBuilder(Connection::class)->setMethods(['getDatabasePlatform', 'quoteIdentifier'])->disableOriginalConstructor()->getMock();
59 $connectionMock->method('getDatabasePlatform')->willReturn($platformMock);
60 $connectionMock->method('quoteIdentifier')->willReturnArgument(0);
61
62 $connectionMigrator = $this->getAccessibleMock(ConnectionMigrator::class, null, [], '', false);
63 $connectionMigrator->_set('connection', $connectionMock);
64 $connectionMigrator->_set('tableAndFieldMaxNameLengthsPerDbPlatform', $this->tableAndFieldMaxNameLengthsPerDbPlatform);
65
66 return $connectionMigrator;
67 }
68
69 /**
70 * Utility method to create a table mock instance with a much too long
71 * table name in any case.
72 *
73 * @return \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
74 */
75 private function getTableMock()
76 {
77 $ridiculouslyLongTableName = 'table_name_that_is_ridiculously_long_' . random_bytes(200);
78 $tableMock = $this->getAccessibleMock(Table::class, ['getQuotedName'], [$ridiculouslyLongTableName]);
79 $tableMock->expects($this->any())->method('getQuotedName')->withAnyParameters()->will($this->returnValue($ridiculouslyLongTableName));
80
81 return $tableMock;
82 }
83
84 /**
85 * @test
86 */
87 public function tableNamesStickToTheMaximumCharactersWhenPrefixedForRemoval()
88 {
89 $connectionMigrator = $this->getConnectionMigratorMock('dbplatform_type1');
90 $tableMock = $this->getTableMock();
91
92 $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
93 $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedTablesToRenames', $originalSchemaDiff);
94
95 $this->assertStringStartsWith('zzz_deleted_', $renamedSchemaDiff->changedTables[0]->newName);
96 $this->assertLessThanOrEqual(
97 $this->tableAndFieldMaxNameLengthsPerDbPlatform['dbplatform_type1']['tables'],
98 strlen($renamedSchemaDiff->changedTables[0]->newName)
99 );
100 }
101
102 /**
103 * @test
104 */
105 public function databasePlatformNamingRestrictionGetsResolved()
106 {
107 $connectionMigrator = $this->getConnectionMigratorMock('dbplatform_type2');
108 $tableMock = $this->getTableMock();
109
110 $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
111 $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedTablesToRenames', $originalSchemaDiff);
112
113 $this->assertLessThanOrEqual(
114 $this->tableAndFieldMaxNameLengthsPerDbPlatform['dbplatform_type1']['tables'],
115 strlen($renamedSchemaDiff->changedTables[0]->newName)
116 );
117 }
118
119 /**
120 * @test
121 */
122 public function whenPassingAnUnknownDatabasePlatformTheDefaultTableAndFieldNameRestrictionsApply()
123 {
124 $connectionMigrator = $this->getConnectionMigratorMock('dummydbplatformthatdoesntexist');
125 $tableMock = $this->getTableMock();
126
127 $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
128 $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedTablesToRenames', $originalSchemaDiff);
129
130 $this->assertLessThanOrEqual(
131 $this->tableAndFieldMaxNameLengthsPerDbPlatform['default']['tables'],
132 strlen($renamedSchemaDiff->changedTables[0]->newName)
133 );
134 }
135
136 /**
137 * @test
138 */
139 public function columnNamesStickToTheMaximumCharactersWhenPrefixedForRemoval()
140 {
141 $connectionMigrator = $this->getConnectionMigratorMock('dbplatform_type1');
142 $tableMock = $this->getAccessibleMock(Table::class, ['getQuotedName'], ['test_table']);
143 $columnMock = $this->getAccessibleMock(
144 Column::class,
145 ['getQuotedName'],
146 [
147 'a_column_name_waaaaay_over_20_characters',
148 $this->getAccessibleMock(\Doctrine\DBAL\Types\StringType::class, [], [], '', false)
149 ]
150 );
151 $columnMock->expects($this->any())->method('getQuotedName')->withAnyParameters()->will($this->returnValue('a_column_name_waaaaay_over_20_characters'));
152
153 $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
154 $originalSchemaDiff->changedTables[0]->removedColumns[] = $columnMock;
155 $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedFieldsToRenames', $originalSchemaDiff);
156
157 $this->assertStringStartsWith('zzz_deleted_', $renamedSchemaDiff->changedTables[0]->changedColumns[0]->column->getName());
158 $this->assertLessThanOrEqual(
159 $this->tableAndFieldMaxNameLengthsPerDbPlatform['dbplatform_type1']['columns'],
160 strlen($renamedSchemaDiff->changedTables[0]->changedColumns[0]->column->getName())
161 );
162 }
163 }