dc90c59c151745011ffeed86b410212167ad5f66
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / Page / PageRepositoryTest.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Tests\Unit\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 use TYPO3\CMS\Core\Utility\GeneralUtility;
17
18 /**
19 * Test case
20 */
21 class PageRepositoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
22 {
23 /**
24 * @var \TYPO3\CMS\Frontend\Page\PageRepository|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
25 */
26 protected $pageSelectObject;
27
28 protected $defaultTcaForPages = array(
29 'ctrl' => array(
30 'label' => 'title',
31 'tstamp' => 'tstamp',
32 'sortby' => 'sorting',
33 'type' => 'doktype',
34 'versioningWS' => true,
35 'origUid' => 't3_origuid',
36 'delete' => 'deleted',
37 'enablecolumns' => array(
38 'disabled' => 'hidden',
39 'starttime' => 'starttime',
40 'endtime' => 'endtime',
41 'fe_group' => 'fe_group'
42 ),
43 ),
44 'columns' => array()
45 );
46
47 /**
48 * Sets up this testcase
49 */
50 protected function setUp()
51 {
52 $GLOBALS['TYPO3_DB'] = $this->getMockBuilder(\TYPO3\CMS\Core\Database\DatabaseConnection::class)
53 ->setMethods(array('exec_SELECTquery', 'sql_fetch_assoc', 'sql_free_result', 'exec_SELECTgetSingleRow'))
54 ->getMock();
55 $this->pageSelectObject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\Page\PageRepository::class, array('getMultipleGroupsWhereClause'));
56 $this->pageSelectObject->expects($this->any())->method('getMultipleGroupsWhereClause')->will($this->returnValue(' AND 1=1'));
57 }
58
59 /**
60 * Tests whether the getPage Hook is called correctly.
61 *
62 * @test
63 */
64 public function isGetPageHookCalled()
65 {
66 // Create a hook mock object
67 $className = $this->getUniqueId('tx_coretest');
68 $getPageHookMock = $this->getMockBuilder(\TYPO3\CMS\Frontend\Page\PageRepositoryGetPageHookInterface::class)
69 ->setMethods(array('getPage_preProcess'))
70 ->setMockClassName($className)
71 ->getMock();
72 // Register hook mock object
73 GeneralUtility::addInstance($className, $getPageHookMock);
74 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPage'][] = $className;
75 // Test if hook is called and register a callback method to check given arguments
76 $getPageHookMock->expects($this->once())->method('getPage_preProcess')->will($this->returnCallback(array($this, 'isGetPagePreProcessCalledCallback')));
77 $this->pageSelectObject->getPage(42, false);
78 }
79
80 /**
81 * Handles the arguments that have been sent to the getPage_preProcess hook
82 *
83 * @param int $uid
84 * @param $disableGroupAccessCheck
85 * @param \TYPO3\CMS\Frontend\Page\PageRepository $parent
86 */
87 public function isGetPagePreProcessCalledCallback($uid, $disableGroupAccessCheck, $parent)
88 {
89 $this->assertEquals(42, $uid);
90 $this->assertFalse($disableGroupAccessCheck);
91 $this->assertTrue($parent instanceof \TYPO3\CMS\Frontend\Page\PageRepository);
92 }
93
94 /////////////////////////////////////////
95 // Tests concerning getPathFromRootline
96 /////////////////////////////////////////
97 /**
98 * @test
99 */
100 public function getPathFromRootLineForEmptyRootLineReturnsEmptyString()
101 {
102 $this->assertEquals('', $this->pageSelectObject->getPathFromRootline(array()));
103 }
104
105 ///////////////////////////////
106 // Tests concerning getExtURL
107 ///////////////////////////////
108 /**
109 * @test
110 */
111 public function getExtUrlForDokType3AndUrlType1AddsHttpSchemeToUrl()
112 {
113 $this->assertEquals('http://www.example.com', $this->pageSelectObject->getExtURL(array(
114 'doktype' => \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_LINK,
115 'urltype' => 1,
116 'url' => 'www.example.com'
117 )));
118 }
119
120 /**
121 * @test
122 */
123 public function getExtUrlForDokType3AndUrlType0PrependsSiteUrl()
124 {
125 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'hello/world/', $this->pageSelectObject->getExtURL(array(
126 'doktype' => \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_LINK,
127 'urltype' => 0,
128 'url' => 'hello/world/'
129 )));
130 }
131
132 /////////////////////////////////////////
133 // Tests concerning shouldFieldBeOverlaid
134 /////////////////////////////////////////
135 /**
136 * @test
137 * @dataProvider getShouldFieldBeOverlaidData
138 */
139 public function shouldFieldBeOverlaid($field, $table, $value, $expected, $comment = '')
140 {
141 $GLOBALS['TCA']['fake_table']['columns'] = array(
142 'exclude' => array(
143 'l10n_mode' => 'exclude',
144 'config' => array('type' => 'input'),
145 ),
146 'mergeIfNotBlank' => array(
147 'l10n_mode' => 'mergeIfNotBlank',
148 'config' => array('type' => 'input'),
149 ),
150 'mergeIfNotBlank_group' => array(
151 'l10n_mode' => 'mergeIfNotBlank',
152 'config' => array('type' => 'group'),
153 ),
154 'default' => array(
155 // no l10n_mode set
156 'config' => array('type' => 'input'),
157 ),
158 'noCopy' => array(
159 'l10n_mode' => 'noCopy',
160 'config' => array('type' => 'input'),
161 ),
162 'prefixLangTitle' => array(
163 'l10n_mode' => 'prefixLangTitle',
164 'config' => array('type' => 'input'),
165 ),
166 );
167
168 $result = $this->pageSelectObject->_call('shouldFieldBeOverlaid', $table, $field, $value);
169 unset($GLOBALS['TCA']['fake_table']);
170
171 $this->assertSame($expected, $result, $comment);
172 }
173
174 /**
175 * Data provider for shouldFieldBeOverlaid
176 */
177 public function getShouldFieldBeOverlaidData()
178 {
179 return array(
180 array('default', 'fake_table', 'foobar', true, 'default is to merge non-empty string'),
181 array('default', 'fake_table', '', true, 'default is to merge empty string'),
182
183 array('exclude', 'fake_table', '', false, 'exclude field with empty string'),
184 array('exclude', 'fake_table', 'foobar', false, 'exclude field with non-empty string'),
185
186 array('mergeIfNotBlank', 'fake_table', '', false, 'mergeIfNotBlank is not merged with empty string'),
187 array('mergeIfNotBlank', 'fake_table', 0, true, 'mergeIfNotBlank is merged with 0'),
188 array('mergeIfNotBlank', 'fake_table', '0', true, 'mergeIfNotBlank is merged with "0"'),
189 array('mergeIfNotBlank', 'fake_table', 'foobar', true, 'mergeIfNotBlank is merged with non-empty string'),
190
191 array('mergeIfNotBlank_group', 'fake_table', '', false, 'mergeIfNotBlank on group is not merged empty string'),
192 array('mergeIfNotBlank_group', 'fake_table', 0, false, 'mergeIfNotBlank on group is not merged with 0'),
193 array('mergeIfNotBlank_group', 'fake_table', '0', false, 'mergeIfNotBlank on group is not merged with "0"'),
194 array('mergeIfNotBlank_group', 'fake_table', 'foobar', true, 'mergeIfNotBlank on group is merged with non-empty string'),
195
196 array('noCopy', 'fake_table', 'foobar', true, 'noCopy is merged with non-empty string'),
197 array('noCopy', 'fake_table', '', true, 'noCopy is merged with empty string'),
198
199 array('prefixLangTitle', 'fake_table', 'foobar', true, 'prefixLangTitle is merged with non-empty string'),
200 array('prefixLangTitle', 'fake_table', '', true, 'prefixLangTitle is merged with empty string'),
201 );
202 }
203
204 ////////////////////////////////
205 // Tests concerning workspaces
206 ////////////////////////////////
207
208 /**
209 * @test
210 */
211 public function noPagesFromWorkspaceAreShownLive()
212 {
213 // initialization
214 $wsid = 987654321;
215 $GLOBALS['TCA'] = array(
216 'pages' => $this->defaultTcaForPages
217 );
218
219 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
220 $this->pageSelectObject->versioningPreview = false;
221 $this->pageSelectObject->versioningWorkspaceId = $wsid;
222 $this->pageSelectObject->init(false);
223
224 // check SQL created by \TYPO3\CMS\Frontend\Page\PageRepository->getPage()
225 $GLOBALS['TYPO3_DB']->expects($this->once())
226 ->method('exec_SELECTgetSingleRow')
227 ->with(
228 '*',
229 'pages',
230 $this->logicalAnd(
231 $this->logicalNot(
232 $this->stringContains('(pages.t3ver_wsid=0 or pages.t3ver_wsid=' . $wsid . ')')
233 ),
234 $this->stringContains('AND pages.t3ver_state<=0')
235 )
236 );
237
238 $this->pageSelectObject->getPage(1);
239 }
240
241 /**
242 * @test
243 */
244 public function previewShowsPagesFromLiveAndCurrentWorkspace()
245 {
246 // initialization
247 $wsid = 987654321;
248 $GLOBALS['TCA'] = array(
249 'pages' => $this->defaultTcaForPages
250 );
251
252 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
253 $this->pageSelectObject->versioningPreview = true;
254 $this->pageSelectObject->versioningWorkspaceId = $wsid;
255 $this->pageSelectObject->init(false);
256
257 // check SQL created by \TYPO3\CMS\Frontend\Page\PageRepository->getPage()
258 $GLOBALS['TYPO3_DB']->expects($this->once())
259 ->method('exec_SELECTgetSingleRow')
260 ->with(
261 '*',
262 'pages',
263 $this->stringContains('(pages.t3ver_wsid=0 or pages.t3ver_wsid=' . $wsid . ')')
264 );
265
266 $this->pageSelectObject->getPage(1);
267 }
268
269 /**
270 * @test
271 */
272 public function getWorkspaceVersionReturnsTheCorrectMethod()
273 {
274 // initialization
275 $wsid = 987654321;
276 $GLOBALS['TCA'] = array(
277 'pages' => $this->defaultTcaForPages
278 );
279 $GLOBALS['SIM_ACCESS_TIME'] = 123;
280
281 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
282 $this->pageSelectObject->versioningPreview = true;
283 $this->pageSelectObject->versioningWorkspaceId = $wsid;
284 $this->pageSelectObject->init(false);
285
286 $GLOBALS['TYPO3_DB']->expects($this->at(0))
287 ->method('exec_SELECTgetSingleRow')
288 ->with(
289 '*',
290 'pages',
291 $this->logicalAnd(
292 $this->stringContains('pid=-1 AND'),
293 $this->stringContains('t3ver_oid=1 AND'),
294 $this->stringContains('t3ver_wsid=' . $wsid . ' AND pages.deleted=0')
295 )
296 )->willReturn(array('uid' => 1));
297 $GLOBALS['TYPO3_DB']->expects($this->at(1))
298 ->method('exec_SELECTgetSingleRow')
299 ->with(
300 'uid',
301 'pages',
302 $this->logicalAnd(
303 $this->stringContains('t3ver_wsid=' . $wsid . ' AND pages.deleted=0 AND pages.hidden=0 AND pages.starttime<=123 AND (pages.endtime=0 OR pages.endtime>123) AND 1=1')
304 )
305 );
306 $this->pageSelectObject->getWorkspaceVersionOfRecord($wsid, 'pages', 1);
307 }
308
309 ////////////////////////////////
310 // Tests concerning versioning
311 ////////////////////////////////
312
313 /**
314 * @test
315 */
316 public function enableFieldsHidesVersionedRecordsAndPlaceholders()
317 {
318 $table = $this->getUniqueId('aTable');
319 $GLOBALS['TCA'] = array(
320 'pages' => $this->defaultTcaForPages,
321 $table => array(
322 'ctrl' => array(
323 'versioningWS' => true
324 )
325 )
326 );
327
328 $this->pageSelectObject->versioningPreview = false;
329 $this->pageSelectObject->init(false);
330
331 $conditions = $this->pageSelectObject->enableFields($table);
332
333 $this->assertThat($conditions, $this->stringContains(' AND ' . $table . '.t3ver_state<=0'), 'Versioning placeholders');
334 $this->assertThat($conditions, $this->stringContains(' AND ' . $table . '.pid<>-1'), 'Records from page -1');
335 }
336
337 /**
338 * @test
339 */
340 public function enableFieldsDoesNotHidePlaceholdersInPreview()
341 {
342 $table = $this->getUniqueId('aTable');
343 $GLOBALS['TCA'] = array(
344 'pages' => $this->defaultTcaForPages,
345 $table => array(
346 'ctrl' => array(
347 'versioningWS' => true
348 )
349 )
350 );
351
352 $this->pageSelectObject->versioningPreview = true;
353 $this->pageSelectObject->init(false);
354
355 $conditions = $this->pageSelectObject->enableFields($table);
356
357 $this->assertThat($conditions, $this->logicalNot($this->stringContains(' AND ' . $table . '.t3ver_state<=0')), 'No versioning placeholders');
358 $this->assertThat($conditions, $this->stringContains(' AND ' . $table . '.pid<>-1'), 'Records from page -1');
359 }
360
361 /**
362 * @test
363 */
364 public function enableFieldsDoesFilterToCurrentAndLiveWorkspaceForRecordsInPreview()
365 {
366 $table = $this->getUniqueId('aTable');
367 $GLOBALS['TCA'] = array(
368 'pages' => $this->defaultTcaForPages,
369 $table => array(
370 'ctrl' => array(
371 'versioningWS' => true
372 )
373 )
374 );
375
376 $this->pageSelectObject->versioningPreview = true;
377 $this->pageSelectObject->versioningWorkspaceId = 2;
378 $this->pageSelectObject->init(false);
379
380 $conditions = $this->pageSelectObject->enableFields($table);
381
382 $this->assertThat($conditions, $this->stringContains(' AND (' . $table . '.t3ver_wsid=0 OR ' . $table . '.t3ver_wsid=2)'), 'No versioning placeholders');
383 }
384
385 /**
386 * @test
387 */
388 public function initSetsPublicPropertyCorrectlyForWorkspacePreview()
389 {
390 $GLOBALS['TCA'] = array(
391 'pages' => $this->defaultTcaForPages,
392 );
393
394 $this->pageSelectObject->versioningPreview = true;
395 $this->pageSelectObject->versioningWorkspaceId = 2;
396 $this->pageSelectObject->init(false);
397
398 $this->assertSame(' AND pages.deleted=0 AND (pages.t3ver_wsid=0 OR pages.t3ver_wsid=2)', $this->pageSelectObject->where_hid_del);
399 }
400
401 /**
402 * @test
403 */
404 public function initSetsPublicPropertyCorrectlyForLive()
405 {
406 $GLOBALS['TCA'] = array(
407 'pages' => $this->defaultTcaForPages,
408 );
409 $GLOBALS['SIM_ACCESS_TIME'] = 123;
410 $this->pageSelectObject->versioningPreview = false;
411 $this->pageSelectObject->versioningWorkspaceId = 0;
412 $this->pageSelectObject->init(false);
413
414 $this->assertSame(' AND pages.deleted=0 AND pages.t3ver_state<=0 AND pages.hidden=0 AND pages.starttime<=123 AND (pages.endtime=0 OR pages.endtime>123)', $this->pageSelectObject->where_hid_del);
415 }
416
417 /**
418 * @test
419 */
420 public function enableFieldsDoesNotHideVersionedRecordsWhenCheckingVersionOverlays()
421 {
422 $table = $this->getUniqueId('aTable');
423 $GLOBALS['TCA'] = array(
424 'pages' => $this->defaultTcaForPages,
425 $table => array(
426 'ctrl' => array(
427 'versioningWS' => true
428 )
429 )
430 );
431
432 $this->pageSelectObject->versioningPreview = true;
433 $this->pageSelectObject->init(false);
434
435 $conditions = $this->pageSelectObject->enableFields($table, -1, array(), true);
436
437 $this->assertThat($conditions, $this->logicalNot($this->stringContains(' AND ' . $table . '.t3ver_state<=0')), 'No versioning placeholders');
438 $this->assertThat($conditions, $this->logicalNot($this->stringContains(' AND ' . $table . '.pid<>-1')), 'No ecords from page -1');
439 }
440 }