[BUGFIX] Add missing namespace parts
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Functional / Category / Collection / CategoryCollectionTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Functional\Category\Collection;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Doctrine\DBAL\Types\Type;
18 use TYPO3\CMS\Core\Category\Collection\CategoryCollection;
19 use TYPO3\CMS\Core\Database\ConnectionPool;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21
22 /**
23 * Test case for \TYPO3\CMS\Core\Category\Collection\CategoryCollection
24 */
25 class CategoryCollectionTest extends \TYPO3\Components\TestingFramework\Core\Functional\FunctionalTestCase
26 {
27 /**
28 * @var CategoryCollection
29 */
30 private $subject;
31
32 /**
33 * @var string
34 */
35 private $tableName = 'tx_foo_5001615c50bed';
36
37 /**
38 * @var array
39 */
40 private $tables = ['sys_category', 'sys_category_record_mm'];
41
42 /**
43 * @var int
44 */
45 private $categoryUid = 0;
46
47 /**
48 * @var array
49 */
50 private $collectionRecord = [];
51
52 /**
53 * @var int
54 */
55 private $numberOfRecords = 5;
56
57 /**
58 * Sets up this test suite.
59 *
60 * @return void
61 */
62 protected function setUp()
63 {
64 parent::setUp();
65 $this->subject = GeneralUtility::makeInstance(CategoryCollection::class, $this->tableName);
66 $this->collectionRecord = [
67 'uid' => 0,
68 'title' => $this->getUniqueId('title'),
69 'description' => $this->getUniqueId('description'),
70 'table_name' => $this->tableName,
71 ];
72 $GLOBALS['TCA'][$this->tableName] = ['ctrl' => []];
73 // prepare environment
74 $this->createDummyTable();
75 $this->populateDummyTable();
76 $this->prepareTables();
77 $this->makeRelationBetweenCategoryAndDummyTable();
78 }
79
80 /**
81 * Tears down this test suite.
82 */
83 protected function tearDown()
84 {
85 $this->purgePreparedTables();
86 $this->dropDummyTable();
87 parent::tearDown();
88 }
89
90 /**
91 * @test
92 * @covers \TYPO3\CMS\Core\Category\Collection\CategoryCollection::fromArray
93 * @return void
94 */
95 public function checkIfFromArrayMethodSetCorrectProperties()
96 {
97 $this->subject->fromArray($this->collectionRecord);
98 $this->assertEquals($this->collectionRecord['uid'], $this->subject->getIdentifier());
99 $this->assertEquals($this->collectionRecord['uid'], $this->subject->getUid());
100 $this->assertEquals($this->collectionRecord['title'], $this->subject->getTitle());
101 $this->assertEquals($this->collectionRecord['description'], $this->subject->getDescription());
102 $this->assertEquals($this->collectionRecord['table_name'], $this->subject->getItemTableName());
103 }
104
105 /**
106 * @test
107 * @covers \TYPO3\CMS\Core\Category\Collection\CategoryCollection::create
108 * @return void
109 */
110 public function canCreateDummyCollection()
111 {
112 $collection = CategoryCollection::create($this->collectionRecord);
113 $this->assertInstanceOf(CategoryCollection::class, $collection);
114 }
115
116 /**
117 * @test
118 * @covers \TYPO3\CMS\Core\Category\Collection\CategoryCollection::create
119 * @return void
120 */
121 public function canCreateDummyCollectionAndFillItems()
122 {
123 $collection = CategoryCollection::create($this->collectionRecord, true);
124 $this->assertInstanceOf(CategoryCollection::class, $collection);
125 }
126
127 /**
128 * @test
129 * @covers \TYPO3\CMS\Core\Category\Collection\CategoryCollection::getCollectedRecords
130 * @return void
131 */
132 public function getCollectedRecordsReturnsEmptyRecordSet()
133 {
134 $method = new \ReflectionMethod(CategoryCollection::class, 'getCollectedRecords');
135 $method->setAccessible(true);
136 $records = $method->invoke($this->subject);
137 $this->assertInternalType('array', $records);
138 $this->assertEmpty($records);
139 }
140
141 /**
142 * @test
143 * @covers \TYPO3\CMS\Core\Category\Collection\CategoryCollection::getStorageTableName
144 * @return void
145 */
146 public function isStorageTableNameEqualsToSysCategory()
147 {
148 $this->assertEquals('sys_category', CategoryCollection::getStorageTableName());
149 }
150
151 /**
152 * @test
153 * @covers \TYPO3\CMS\Core\Category\Collection\CategoryCollection::getStorageItemsField
154 * @return void
155 */
156 public function isStorageItemsFieldEqualsToItems()
157 {
158 $this->assertEquals('items', CategoryCollection::getStorageItemsField());
159 }
160
161 /**
162 * @test
163 * @return void
164 */
165 public function canLoadADummyCollectionFromDatabase()
166 {
167 /** @var $collection CategoryCollection */
168 $collection = CategoryCollection::load($this->categoryUid, true, $this->tableName);
169 // Check the number of record
170 $this->assertEquals($this->numberOfRecords, $collection->count());
171 // Check that the first record is the one expected
172 $queryBuilder = $this->getConnectionPool()
173 ->getQueryBuilderForTable($this->tableName);
174 $queryBuilder->getRestrictions()->removeAll();
175 $statement = $queryBuilder
176 ->select('*')
177 ->from($this->tableName)
178 ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT)))
179 ->execute();
180 $record = $statement->fetch();
181 $collection->rewind();
182 $this->assertEquals($record, $collection->current());
183 // Add a new record
184 $fakeRecord = [
185 'uid' => $this->numberOfRecords + 1,
186 'pid' => 0,
187 'title' => $this->getUniqueId('title'),
188 'categories' => 0
189 ];
190 // Check the number of records
191 $collection->add($fakeRecord);
192 $this->assertEquals($this->numberOfRecords + 1, $collection->count());
193 }
194
195 /**
196 * @test
197 * @return void
198 */
199 public function canLoadADummyCollectionFromDatabaseAndAddRecord()
200 {
201 $collection = CategoryCollection::load($this->categoryUid, true, $this->tableName);
202 // Add a new record
203 $fakeRecord = [
204 'uid' => $this->numberOfRecords + 1,
205 'pid' => 0,
206 'title' => $this->getUniqueId('title'),
207 'categories' => 0
208 ];
209 // Check the number of records
210 $collection->add($fakeRecord);
211 $this->assertEquals($this->numberOfRecords + 1, $collection->count());
212 }
213
214 /**
215 * @test
216 * @return void
217 */
218 public function canLoadADummyCollectionWithoutContentFromDatabase()
219 {
220 /** @var $collection CategoryCollection */
221 $collection = CategoryCollection::load($this->categoryUid, false, $this->tableName);
222 // Check the number of record
223 $this->assertEquals(0, $collection->count());
224 }
225
226 /**
227 * @test
228 * @return void
229 */
230 public function canLoadADummyCollectionFromDatabaseAfterRemoveOneRelation()
231 {
232 // Remove one relation
233 $fakeName = [
234 'tablenames' => $this->getUniqueId('name')
235 ];
236 $this->getConnectionPool()
237 ->getConnectionForTable('sys_category_record_mm')
238 ->update('sys_category_record_mm', $fakeName, ['uid_foreign' => 1]);
239 // Check the number of records
240 $collection = CategoryCollection::load($this->categoryUid, true, $this->tableName);
241 $this->assertEquals($this->numberOfRecords - 1, $collection->count());
242 }
243
244 /********************/
245 /* INTERNAL METHODS */
246 /********************/
247 /**
248 * Create dummy table for testing purpose
249 *
250 * @return void
251 */
252 private function populateDummyTable()
253 {
254 for ($index = 1; $index <= $this->numberOfRecords; $index++) {
255 $values = [
256 'title' => $this->getUniqueId('title')
257 ];
258 $this->getConnectionPool()
259 ->getConnectionForTable($this->tableName)
260 ->insert($this->tableName, $values);
261 }
262 }
263
264 /**
265 * Make relation between tables
266 *
267 * @return void
268 */
269 private function makeRelationBetweenCategoryAndDummyTable()
270 {
271 for ($index = 1; $index <= $this->numberOfRecords; $index++) {
272 $values = [
273 'uid_local' => $this->categoryUid,
274 'uid_foreign' => $index,
275 'tablenames' => $this->tableName,
276 'fieldname' => 'categories'
277 ];
278 $this->getConnectionPool()
279 ->getConnectionForTable('sys_category_record_mm')
280 ->insert('sys_category_record_mm', $values);
281 }
282 }
283
284 /**
285 * Create dummy table for testing purpose
286 *
287 * @return void
288 */
289 private function createDummyTable()
290 {
291 $connection = $this->getConnectionPool()
292 ->getConnectionForTable($this->tableName);
293 $currentSchema = $connection->getSchemaManager()->createSchema();
294 $targetSchema = clone $currentSchema;
295
296 $table = $targetSchema->createTable($this->tableName);
297 $table->addColumn('uid', Type::INTEGER, ['length' => 11, 'unsigned' => true, 'autoincrement' => true]);
298 $table->addColumn('pid', Type::INTEGER, ['length' => 11, 'notnull' => true, 'default' => 0]);
299 $table->addColumn('title', Type::STRING);
300 $table->addColumn('tcategories', Type::INTEGER, ['length' => 11, 'unsigned' => true, 'notnull' => true, 'default' => 0]);
301 $table->addColumn('sys_category_is_dummy_record', Type::INTEGER, ['length' => 11, 'unsigned' => true, 'notnull' => true, 'default' => 0]);
302 $table->setPrimaryKey(['uid']);
303
304 $queries = $currentSchema->getMigrateToSql($targetSchema, $connection->getDatabasePlatform());
305 foreach ($queries as $query) {
306 $connection->query($query);
307 }
308 }
309
310 /**
311 * Drop dummy table
312 *
313 * @return void
314 */
315 private function dropDummyTable()
316 {
317 $connection = $this->getConnectionPool()
318 ->getConnectionForTable($this->tableName);
319 $currentSchema = $connection->getSchemaManager()->createSchema();
320 $targetSchema = clone $currentSchema;
321
322 $targetSchema->dropTable($this->tableName);
323
324 $queries = $currentSchema->getMigrateToSql($targetSchema, $connection->getDatabasePlatform());
325 foreach ($queries as $query) {
326 $connection->query($query);
327 }
328 }
329
330 /**
331 * Add is_dummy_record record and create dummy record
332 *
333 * @return void
334 */
335 private function prepareTables()
336 {
337 $connection = $this->getConnectionPool()
338 ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
339 $currentSchema = $connection->getSchemaManager()->createSchema();
340 $targetSchema = clone $currentSchema;
341
342 $columnOptions = ['length' => 1, 'unsigned' => true, 'notnull' => true, 'default' => 0];
343 foreach ($this->tables as $table) {
344 $targetSchema
345 ->getTable($table)
346 ->addColumn('is_dummy_record', Type::SMALLINT, $columnOptions);
347 }
348
349 $queries = $currentSchema->getMigrateToSql($targetSchema, $connection->getDatabasePlatform());
350 foreach ($queries as $query) {
351 $connection->query($query);
352 }
353
354 $values = [
355 'title' => $this->getUniqueId('title'),
356 'l10n_diffsource' => '',
357 'description' => '',
358 'is_dummy_record' => 1
359 ];
360
361 $connection->insert('sys_category', $values);
362 $this->categoryUid = $connection->lastInsertId('sys_category');
363 }
364
365 /**
366 * Drops previously added dummy columns from core tables.
367 *
368 * @throws \Doctrine\DBAL\DBALException
369 * @throws \Doctrine\DBAL\Schema\SchemaException
370 * @see prepareTables()
371 */
372 private function purgePreparedTables()
373 {
374 $connection = $this->getConnectionPool()
375 ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
376 $currentSchema = $connection->getSchemaManager()->createSchema();
377 $targetSchema = clone $currentSchema;
378
379 foreach ($this->tables as $table) {
380 $targetSchema->getTable($table)->dropColumn('is_dummy_record');
381 }
382
383 $queries = $currentSchema->getMigrateToSql($targetSchema, $connection->getDatabasePlatform());
384 foreach ($queries as $query) {
385 $connection->query($query);
386 }
387 }
388 }