[BUGFIX] Add missing namespace parts
[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\Components\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->versioningPreview = true;
314 $this->pageRepo->versioningWorkspaceId = 2;
315 $this->pageRepo->init(false);
316
317 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
318
319 $expectedSQL = sprintf(
320 ' AND (%s = 0) AND ((%s = 0) OR (%s = 2))',
321 $connection->quoteIdentifier('pages.deleted'),
322 $connection->quoteIdentifier('pages.t3ver_wsid'),
323 $connection->quoteIdentifier('pages.t3ver_wsid')
324 );
325
326 $this->assertSame($expectedSQL, $this->pageRepo->where_hid_del);
327 }
328
329 /**
330 * @test
331 */
332 public function initSetsPublicPropertyCorrectlyForLive()
333 {
334 $GLOBALS['SIM_ACCESS_TIME'] = 123;
335
336 $this->pageRepo->versioningPreview = false;
337 $this->pageRepo->versioningWorkspaceId = 0;
338 $this->pageRepo->init(false);
339
340 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
341 $expectedSQL = sprintf(
342 ' AND (%s = 0) AND (%s <= 0) AND (%s = 0) AND (%s <= 123) AND ((%s = 0) OR (%s > 123))',
343 $connection->quoteIdentifier('pages.deleted'),
344 $connection->quoteIdentifier('pages.t3ver_state'),
345 $connection->quoteIdentifier('pages.hidden'),
346 $connection->quoteIdentifier('pages.starttime'),
347 $connection->quoteIdentifier('pages.endtime'),
348 $connection->quoteIdentifier('pages.endtime')
349 );
350
351 $this->assertSame($expectedSQL, $this->pageRepo->where_hid_del);
352 }
353
354 ////////////////////////////////
355 // Tests concerning workspaces
356 ////////////////////////////////
357
358 /**
359 * @test
360 */
361 public function noPagesFromWorkspaceAreShownLive()
362 {
363 // initialization
364 $wsid = 987654321;
365
366 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
367 $this->pageRepo->versioningPreview = false;
368 $this->pageRepo->versioningWorkspaceId = $wsid;
369 $this->pageRepo->init(false);
370
371 $this->assertSame([], $this->pageRepo->getPage(11));
372 }
373
374 /**
375 * @test
376 */
377 public function previewShowsPagesFromLiveAndCurrentWorkspace()
378 {
379 // initialization
380 $wsid = 987654321;
381
382 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
383 $this->pageRepo->versioningPreview = true;
384 $this->pageRepo->versioningWorkspaceId = $wsid;
385 $this->pageRepo->init(false);
386
387 $pageRec = $this->pageRepo->getPage(11);
388
389 $this->assertSame(11, $pageRec['uid']);
390 $this->assertSame(11, $pageRec['t3ver_oid']);
391 $this->assertSame(987654321, $pageRec['t3ver_wsid']);
392 $this->assertSame(-1, $pageRec['t3ver_state']);
393 $this->assertSame('First draft version', $pageRec['t3ver_label']);
394 }
395
396 /**
397 * @test
398 */
399 public function getWorkspaceVersionReturnsTheCorrectMethod()
400 {
401 // initialization
402 $wsid = 987654321;
403
404 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
405 $this->pageRepo->versioningPreview = true;
406 $this->pageRepo->versioningWorkspaceId = $wsid;
407 $this->pageRepo->init(false);
408
409 $pageRec = $this->pageRepo->getWorkspaceVersionOfRecord($wsid, 'pages', 11);
410
411 $this->assertSame(12, $pageRec['uid']);
412 $this->assertSame(11, $pageRec['t3ver_oid']);
413 $this->assertSame(987654321, $pageRec['t3ver_wsid']);
414 $this->assertSame(-1, $pageRec['t3ver_state']);
415 $this->assertSame('First draft version', $pageRec['t3ver_label']);
416 }
417
418 ////////////////////////////////
419 // Tests concerning versioning
420 ////////////////////////////////
421
422 /**
423 * @test
424 */
425 public function enableFieldsHidesVersionedRecordsAndPlaceholders()
426 {
427 $table = $this->getUniqueId('aTable');
428 $GLOBALS['TCA'][$table] = [
429 'ctrl' => [
430 'versioningWS' => true
431 ]
432 ];
433
434 $this->pageRepo->versioningPreview = false;
435 $this->pageRepo->init(false);
436
437 $conditions = $this->pageRepo->enableFields($table);
438 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
439
440 $this->assertThat(
441 $conditions,
442 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)'),
443 'Versioning placeholders'
444 );
445 $this->assertThat(
446 $conditions,
447 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)'),
448 'Records from page -1'
449 );
450 }
451
452 /**
453 * @test
454 */
455 public function enableFieldsDoesNotHidePlaceholdersInPreview()
456 {
457 $table = $this->getUniqueId('aTable');
458 $GLOBALS['TCA'][$table] = [
459 'ctrl' => [
460 'versioningWS' => true
461 ]
462 ];
463
464 $this->pageRepo->versioningPreview = true;
465 $this->pageRepo->init(false);
466
467 $conditions = $this->pageRepo->enableFields($table);
468 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
469
470 $this->assertThat(
471 $conditions,
472 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)')),
473 'No versioning placeholders'
474 );
475 $this->assertThat(
476 $conditions,
477 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)'),
478 'Records from page -1'
479 );
480 }
481
482 /**
483 * @test
484 */
485 public function enableFieldsDoesFilterToCurrentAndLiveWorkspaceForRecordsInPreview()
486 {
487 $table = $this->getUniqueId('aTable');
488 $GLOBALS['TCA'][$table] = [
489 'ctrl' => [
490 'versioningWS' => true
491 ]
492 ];
493
494 $this->pageRepo->versioningPreview = true;
495 $this->pageRepo->versioningWorkspaceId = 2;
496 $this->pageRepo->init(false);
497
498 $conditions = $this->pageRepo->enableFields($table);
499 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
500
501 $this->assertThat(
502 $conditions,
503 $this->stringContains(' AND ((' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 2))'),
504 'No versioning placeholders'
505 );
506 }
507
508 /**
509 * @test
510 */
511 public function enableFieldsDoesNotHideVersionedRecordsWhenCheckingVersionOverlays()
512 {
513 $table = $this->getUniqueId('aTable');
514 $GLOBALS['TCA'][$table] = [
515 'ctrl' => [
516 'versioningWS' => true
517 ]
518 ];
519
520 $this->pageRepo->versioningPreview = true;
521 $this->pageRepo->init(false);
522
523 $conditions = $this->pageRepo->enableFields($table, -1, [], true);
524 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
525
526 $this->assertThat(
527 $conditions,
528 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)')),
529 'No versioning placeholders'
530 );
531 $this->assertThat(
532 $conditions,
533 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)')),
534 'No necords from page -1'
535 );
536 }
537
538 protected function assertOverlayRow($row)
539 {
540 $this->assertInternalType('array', $row);
541
542 $this->assertArrayHasKey('_PAGES_OVERLAY', $row);
543 $this->assertArrayHasKey('_PAGES_OVERLAY_UID', $row);
544 $this->assertArrayHasKey('_PAGES_OVERLAY_LANGUAGE', $row);
545
546 $this->assertTrue($row['_PAGES_OVERLAY']);
547 }
548
549 protected function assertNotOverlayRow($row)
550 {
551 $this->assertInternalType('array', $row);
552
553 $this->assertFalse(isset($row['_PAGES_OVERLAY']));
554 $this->assertFalse(isset($row['_PAGES_OVERLAY_UID']));
555 $this->assertFalse(isset($row['_PAGES_OVERLAY_LANGUAGE']));
556 }
557 }