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