[!!!][TASK] Drop "documentation" extension
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Functional / Page / PageRepositoryTest.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Tests\Functional\Page;
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 Prophecy\Argument;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Frontend\Page\PageRepository;
21 use TYPO3\CMS\Frontend\Page\PageRepositoryGetPageHookInterface;
22
23 /**
24 * Test case
25 */
26 class PageRepositoryTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
27 {
28 protected $coreExtensionsToLoad = ['frontend'];
29
30 /**
31 * @var \TYPO3\CMS\Frontend\Page\PageRepository
32 */
33 protected $pageRepo;
34
35 protected function setUp()
36 {
37 parent::setUp();
38 $GLOBALS['TSFE']->gr_list = '';
39 $this->importDataSet(__DIR__ . '/../Fixtures/pages.xml');
40 $this->pageRepo = new PageRepository();
41 $this->pageRepo->init(false);
42 }
43
44 /**
45 * @test
46 */
47 public function getMenuSingleUidRoot()
48 {
49 $rows = $this->pageRepo->getMenu(1, 'uid, title');
50 $this->assertArrayHasKey(2, $rows);
51 $this->assertArrayHasKey(3, $rows);
52 $this->assertArrayHasKey(4, $rows);
53 $this->assertCount(3, $rows);
54 }
55
56 /**
57 * @test
58 */
59 public function getMenuSingleUidSubpage()
60 {
61 $rows = $this->pageRepo->getMenu(2, 'uid, title');
62 $this->assertArrayHasKey(5, $rows);
63 $this->assertArrayHasKey(6, $rows);
64 $this->assertArrayHasKey(7, $rows);
65 $this->assertCount(3, $rows);
66 }
67
68 /**
69 * @test
70 */
71 public function getMenuMultipleUid()
72 {
73 $rows = $this->pageRepo->getMenu([2, 3], 'uid, title');
74 $this->assertArrayHasKey(5, $rows);
75 $this->assertArrayHasKey(6, $rows);
76 $this->assertArrayHasKey(7, $rows);
77 $this->assertArrayHasKey(8, $rows);
78 $this->assertArrayHasKey(9, $rows);
79 $this->assertCount(5, $rows);
80 }
81
82 /**
83 * @test
84 */
85 public function getMenuPageOverlay()
86 {
87 $this->pageRepo->sys_language_uid = 1;
88
89 $rows = $this->pageRepo->getMenu([2, 3], 'uid, title');
90 $this->assertEquals('Attrappe 1-2-5', $rows[5]['title']);
91 $this->assertEquals('Attrappe 1-2-6', $rows[6]['title']);
92 $this->assertEquals('Dummy 1-2-7', $rows[7]['title']);
93 $this->assertEquals('Dummy 1-3-8', $rows[8]['title']);
94 $this->assertEquals('Attrappe 1-3-9', $rows[9]['title']);
95 $this->assertCount(5, $rows);
96 }
97
98 /**
99 * @test
100 */
101 public function getPageOverlayById()
102 {
103 $row = $this->pageRepo->getPageOverlay(1, 1);
104 $this->assertOverlayRow($row);
105 $this->assertEquals('Wurzel 1', $row['title']);
106 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
107 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
108 }
109
110 /**
111 * @test
112 */
113 public function getPageOverlayByIdWithoutTranslation()
114 {
115 $row = $this->pageRepo->getPageOverlay(4, 1);
116 $this->assertInternalType('array', $row);
117 $this->assertCount(0, $row);
118 }
119
120 /**
121 * @test
122 */
123 public function getPageOverlayByRow()
124 {
125 $orig = $this->pageRepo->getPage(1);
126 $row = $this->pageRepo->getPageOverlay($orig, 1);
127 $this->assertOverlayRow($row);
128 $this->assertEquals(1, $row['uid']);
129 $this->assertEquals('Wurzel 1', $row['title']);
130 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
131 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
132 }
133
134 /**
135 * @test
136 */
137 public function getPageOverlayByRowWithoutTranslation()
138 {
139 $orig = $this->pageRepo->getPage(4);
140 $row = $this->pageRepo->getPageOverlay($orig, 1);
141 $this->assertInternalType('array', $row);
142 $this->assertEquals(4, $row['uid']);
143 $this->assertEquals('Dummy 1-4', $row['title']);//original title
144 }
145
146 /**
147 * @test
148 */
149 public function getPagesOverlayByIdSingle()
150 {
151 $this->pageRepo->sys_language_uid = 1;
152 $rows = $this->pageRepo->getPagesOverlay([1]);
153 $this->assertInternalType('array', $rows);
154 $this->assertCount(1, $rows);
155 $this->assertArrayHasKey(0, $rows);
156
157 $row = $rows[0];
158 $this->assertOverlayRow($row);
159 $this->assertEquals('Wurzel 1', $row['title']);
160 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
161 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
162 }
163
164 /**
165 * @test
166 */
167 public function getPagesOverlayByIdMultiple()
168 {
169 $this->pageRepo->sys_language_uid = 1;
170 $rows = $this->pageRepo->getPagesOverlay([1, 5]);
171 $this->assertInternalType('array', $rows);
172 $this->assertCount(2, $rows);
173 $this->assertArrayHasKey(0, $rows);
174 $this->assertArrayHasKey(1, $rows);
175
176 $row = $rows[0];
177 $this->assertOverlayRow($row);
178 $this->assertEquals('Wurzel 1', $row['title']);
179 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
180 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
181
182 $row = $rows[1];
183 $this->assertOverlayRow($row);
184 $this->assertEquals('Attrappe 1-2-5', $row['title']);
185 $this->assertEquals('904', $row['_PAGES_OVERLAY_UID']);
186 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
187 }
188
189 /**
190 * @test
191 */
192 public function getPagesOverlayByIdMultipleSomeNotOverlaid()
193 {
194 $this->pageRepo->sys_language_uid = 1;
195 $rows = $this->pageRepo->getPagesOverlay([1, 4, 5, 8]);
196 $this->assertInternalType('array', $rows);
197 $this->assertCount(2, $rows);
198 $this->assertArrayHasKey(0, $rows);
199 $this->assertArrayHasKey(2, $rows);
200
201 $row = $rows[0];
202 $this->assertOverlayRow($row);
203 $this->assertEquals('Wurzel 1', $row['title']);
204
205 $row = $rows[2];
206 $this->assertOverlayRow($row);
207 $this->assertEquals('Attrappe 1-2-5', $row['title']);
208 }
209
210 /**
211 * @test
212 */
213 public function getPagesOverlayByRowSingle()
214 {
215 $origRow = $this->pageRepo->getPage(1);
216
217 $this->pageRepo->sys_language_uid = 1;
218 $rows = $this->pageRepo->getPagesOverlay([$origRow]);
219 $this->assertInternalType('array', $rows);
220 $this->assertCount(1, $rows);
221 $this->assertArrayHasKey(0, $rows);
222
223 $row = $rows[0];
224 $this->assertOverlayRow($row);
225 $this->assertEquals('Wurzel 1', $row['title']);
226 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
227 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
228 }
229
230 /**
231 * @test
232 */
233 public function getPagesOverlayByRowMultiple()
234 {
235 $orig1 = $this->pageRepo->getPage(1);
236 $orig2 = $this->pageRepo->getPage(5);
237
238 $this->pageRepo->sys_language_uid = 1;
239 $rows = $this->pageRepo->getPagesOverlay([1 => $orig1, 5 => $orig2]);
240 $this->assertInternalType('array', $rows);
241 $this->assertCount(2, $rows);
242 $this->assertArrayHasKey(1, $rows);
243 $this->assertArrayHasKey(5, $rows);
244
245 $row = $rows[1];
246 $this->assertOverlayRow($row);
247 $this->assertEquals('Wurzel 1', $row['title']);
248 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
249 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
250
251 $row = $rows[5];
252 $this->assertOverlayRow($row);
253 $this->assertEquals('Attrappe 1-2-5', $row['title']);
254 $this->assertEquals('904', $row['_PAGES_OVERLAY_UID']);
255 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
256 }
257
258 /**
259 * @test
260 */
261 public function getPagesOverlayByRowMultipleSomeNotOverlaid()
262 {
263 $orig1 = $this->pageRepo->getPage(1);
264 $orig2 = $this->pageRepo->getPage(7);
265 $orig3 = $this->pageRepo->getPage(9);
266
267 $this->pageRepo->sys_language_uid = 1;
268 $rows = $this->pageRepo->getPagesOverlay([$orig1, $orig2, $orig3]);
269 $this->assertInternalType('array', $rows);
270 $this->assertCount(3, $rows);
271 $this->assertArrayHasKey(0, $rows);
272 $this->assertArrayHasKey(1, $rows);
273 $this->assertArrayHasKey(2, $rows);
274
275 $row = $rows[0];
276 $this->assertOverlayRow($row);
277 $this->assertEquals('Wurzel 1', $row['title']);
278
279 $row = $rows[1];
280 $this->assertNotOverlayRow($row);
281 $this->assertEquals('Dummy 1-2-7', $row['title']);
282
283 $row = $rows[2];
284 $this->assertOverlayRow($row);
285 $this->assertEquals('Attrappe 1-3-9', $row['title']);
286 }
287
288 /**
289 * Tests whether the getPage Hook is called correctly.
290 *
291 * @test
292 */
293 public function isGetPageHookCalled()
294 {
295 // Create a hook mock object
296 $getPageHookProphet = $this->prophesize(\stdClass::class);
297 $getPageHookProphet->willImplement(PageRepositoryGetPageHookInterface::class);
298 $getPageHookProphet->getPage_preProcess(42, false, Argument::type(PageRepository::class))->shouldBeCalled();
299 $getPageHookMock = $getPageHookProphet->reveal();
300 $className = get_class($getPageHookMock);
301
302 // Register hook mock object
303 GeneralUtility::addInstance($className, $getPageHookMock);
304 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPage'][] = $className;
305 $this->pageRepo->getPage(42, false);
306 }
307
308 /**
309 * @test
310 */
311 public function initSetsPublicPropertyCorrectlyForWorkspacePreview()
312 {
313 $this->pageRepo->versioningWorkspaceId = 2;
314 $this->pageRepo->init(false);
315
316 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
317
318 $expectedSQL = sprintf(
319 ' AND (%s = 0) AND ((%s = 0) OR (%s = 2))',
320 $connection->quoteIdentifier('pages.deleted'),
321 $connection->quoteIdentifier('pages.t3ver_wsid'),
322 $connection->quoteIdentifier('pages.t3ver_wsid')
323 );
324
325 $this->assertSame($expectedSQL, $this->pageRepo->where_hid_del);
326 }
327
328 /**
329 * @test
330 */
331 public function initSetsPublicPropertyCorrectlyForLive()
332 {
333 $GLOBALS['SIM_ACCESS_TIME'] = 123;
334
335 $this->pageRepo->versioningWorkspaceId = 0;
336 $this->pageRepo->init(false);
337
338 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
339 $expectedSQL = sprintf(
340 ' AND (%s = 0) AND (%s <= 0) AND (%s = 0) AND (%s <= 123) AND ((%s = 0) OR (%s > 123))',
341 $connection->quoteIdentifier('pages.deleted'),
342 $connection->quoteIdentifier('pages.t3ver_state'),
343 $connection->quoteIdentifier('pages.hidden'),
344 $connection->quoteIdentifier('pages.starttime'),
345 $connection->quoteIdentifier('pages.endtime'),
346 $connection->quoteIdentifier('pages.endtime')
347 );
348
349 $this->assertSame($expectedSQL, $this->pageRepo->where_hid_del);
350 }
351
352 ////////////////////////////////
353 // Tests concerning workspaces
354 ////////////////////////////////
355
356 /**
357 * @test
358 */
359 public function previewShowsPagesFromLiveAndCurrentWorkspace()
360 {
361 // initialization
362 $wsid = 987654321;
363
364 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
365 $this->pageRepo->versioningWorkspaceId = $wsid;
366 $this->pageRepo->init(false);
367
368 $pageRec = $this->pageRepo->getPage(11);
369
370 $this->assertEquals(11, $pageRec['uid']);
371 $this->assertEquals(11, $pageRec['t3ver_oid']);
372 $this->assertEquals(987654321, $pageRec['t3ver_wsid']);
373 $this->assertEquals(-1, $pageRec['t3ver_state']);
374 $this->assertSame('First draft version', $pageRec['t3ver_label']);
375 }
376
377 /**
378 * @test
379 */
380 public function getWorkspaceVersionReturnsTheCorrectMethod()
381 {
382 // initialization
383 $wsid = 987654321;
384
385 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
386 $this->pageRepo->versioningWorkspaceId = $wsid;
387 $this->pageRepo->init(false);
388
389 $pageRec = $this->pageRepo->getWorkspaceVersionOfRecord($wsid, 'pages', 11);
390
391 $this->assertEquals(12, $pageRec['uid']);
392 $this->assertEquals(11, $pageRec['t3ver_oid']);
393 $this->assertEquals(987654321, $pageRec['t3ver_wsid']);
394 $this->assertEquals(-1, $pageRec['t3ver_state']);
395 $this->assertSame('First draft version', $pageRec['t3ver_label']);
396 }
397
398 ////////////////////////////////
399 // Tests concerning versioning
400 ////////////////////////////////
401
402 /**
403 * @test
404 */
405 public function enableFieldsHidesVersionedRecordsAndPlaceholders()
406 {
407 $table = $this->getUniqueId('aTable');
408 $GLOBALS['TCA'][$table] = [
409 'ctrl' => [
410 'versioningWS' => true
411 ]
412 ];
413
414 $this->pageRepo->versioningWorkspaceId = 0;
415 $this->pageRepo->init(false);
416
417 $conditions = $this->pageRepo->enableFields($table);
418 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
419
420 $this->assertThat(
421 $conditions,
422 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)'),
423 'Versioning placeholders'
424 );
425 $this->assertThat(
426 $conditions,
427 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)'),
428 'Records from page -1'
429 );
430 }
431
432 /**
433 * @test
434 */
435 public function enableFieldsDoesNotHidePlaceholdersInPreview()
436 {
437 $table = $this->getUniqueId('aTable');
438 $GLOBALS['TCA'][$table] = [
439 'ctrl' => [
440 'versioningWS' => true
441 ]
442 ];
443
444 $this->pageRepo->versioningWorkspaceId = 13;
445 $this->pageRepo->init(false);
446
447 $conditions = $this->pageRepo->enableFields($table);
448 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
449
450 $this->assertThat(
451 $conditions,
452 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)')),
453 'No versioning placeholders'
454 );
455 $this->assertThat(
456 $conditions,
457 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)'),
458 'Records from page -1'
459 );
460 }
461
462 /**
463 * @test
464 */
465 public function enableFieldsDoesFilterToCurrentAndLiveWorkspaceForRecordsInPreview()
466 {
467 $table = $this->getUniqueId('aTable');
468 $GLOBALS['TCA'][$table] = [
469 'ctrl' => [
470 'versioningWS' => true
471 ]
472 ];
473
474 $this->pageRepo->versioningWorkspaceId = 2;
475 $this->pageRepo->init(false);
476
477 $conditions = $this->pageRepo->enableFields($table);
478 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
479
480 $this->assertThat(
481 $conditions,
482 $this->stringContains(' AND ((' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 2))'),
483 'No versioning placeholders'
484 );
485 }
486
487 /**
488 * @test
489 */
490 public function enableFieldsDoesNotHideVersionedRecordsWhenCheckingVersionOverlays()
491 {
492 $table = $this->getUniqueId('aTable');
493 $GLOBALS['TCA'][$table] = [
494 'ctrl' => [
495 'versioningWS' => true
496 ]
497 ];
498
499 $this->pageRepo->versioningWorkspaceId = 23;
500 $this->pageRepo->init(false);
501
502 $conditions = $this->pageRepo->enableFields($table, -1, [], true);
503 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
504
505 $this->assertThat(
506 $conditions,
507 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)')),
508 'No versioning placeholders'
509 );
510 $this->assertThat(
511 $conditions,
512 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)')),
513 'No records from page -1'
514 );
515 }
516
517 protected function assertOverlayRow($row)
518 {
519 $this->assertInternalType('array', $row);
520
521 $this->assertArrayHasKey('_PAGES_OVERLAY', $row);
522 $this->assertArrayHasKey('_PAGES_OVERLAY_UID', $row);
523 $this->assertArrayHasKey('_PAGES_OVERLAY_LANGUAGE', $row);
524
525 $this->assertTrue($row['_PAGES_OVERLAY']);
526 }
527
528 protected function assertNotOverlayRow($row)
529 {
530 $this->assertInternalType('array', $row);
531
532 $this->assertFalse(isset($row['_PAGES_OVERLAY']));
533 $this->assertFalse(isset($row['_PAGES_OVERLAY_UID']));
534 $this->assertFalse(isset($row['_PAGES_OVERLAY_LANGUAGE']));
535 }
536 }