‪TYPO3CMS  10.4
RootlineUtilityTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
27 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
28 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
29 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
30 
34 class ‪RootlineUtilityTest extends FunctionalTestCase
35 {
37 
38  protected const ‪LANGUAGE_PRESETS = [
39  'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_US.UTF8', 'iso' => 'en', 'hrefLang' => 'en-US', 'direction' => ''],
40  'FR' => ['id' => 1, 'title' => 'French', 'locale' => 'fr_FR.UTF8', 'iso' => 'fr', 'hrefLang' => 'fr-FR', 'direction' => ''],
41  'FR-CA' => ['id' => 2, 'title' => 'Franco-Canadian', 'locale' => 'fr_CA.UTF8', 'iso' => 'fr', 'hrefLang' => 'fr-CA', 'direction' => ''],
42  'ES' => ['id' => 3, 'title' => 'Spanish', 'locale' => 'es_ES.UTF8', 'iso' => 'es', 'hrefLang' => 'es-ES', 'direction' => ''],
43  ];
44 
48  protected ‪$coreExtensionsToLoad = ['workspaces'];
49 
50  protected function ‪setUp(): void
51  {
52  parent::setUp();
54 
56  'main',
57  $this->‪buildSiteConfiguration(1000, 'https://acme.com/'),
58  [
59  $this->‪buildDefaultLanguageConfiguration('EN', '/'),
60  $this->‪buildLanguageConfiguration('FR', '/fr/', ['EN']),
61  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
62  ]
63  );
64  $this->withDatabaseSnapshot(function () {
65  $this->‪setUpDatabase();
66  });
67  }
68 
69  public static function ‪setUpBeforeClass(): void
70  {
71  parent::setUpBeforeClass();
72  static::initializeDatabaseSnapshot();
73  }
74 
75  public static function ‪tearDownAfterClass(): void
76  {
78  static::destroyDatabaseSnapshot();
79  parent::tearDownAfterClass();
80  }
81 
82  protected function ‪setUpDatabase()
83  {
84  $backendUser = $this->setUpBackendUserFromFixture(1);
86 
87  $factory = DataHandlerFactory::fromYamlFile(__DIR__ . '/Fixtures/RootlineScenario.yaml');
88  $writer = DataHandlerWriter::withBackendUser($backendUser);
89  $writer->invokeFactory($factory);
90  static::failIfArrayIsNotEmpty(
91  $writer->getErrors()
92  );
93  }
94 
99  {
100  $rootPageUid = 1000;
101  $subject = new RootlineUtility($rootPageUid);
102 
103  $result = $subject->get();
104 
105  self::assertCount(1, $result);
106  self::assertSame($rootPageUid, (int)$result[0]['uid']);
107  }
108 
113  {
114  $rootPageUid = 1000;
115  $subject = new RootlineUtility($rootPageUid);
116 
117  unset(‪$GLOBALS['TCA']['pages']['columns']);
118  $result = $subject->get();
119 
120  self::assertCount(1, $result);
121  self::assertSame($rootPageUid, (int)$result[0]['uid']);
122  }
123 
128  {
129  $rootPageUid = 1000;
130  $subject = new RootlineUtility($rootPageUid);
131 
132  ‪$GLOBALS['TCA']['pages']['columns'] = 'This is not an array.';
133  $result = $subject->get();
134 
135  self::assertCount(1, $result);
136  self::assertSame($rootPageUid, (int)$result[0]['uid']);
137  }
138 
143  {
144  $context = GeneralUtility::makeInstance(Context::class);
145  $context->setAspect('workspace', new WorkspaceAspect(0));
146  $subject = new RootlineUtility(1330, '', $context);
147  $result = $subject->get();
148 
149  $expected = [
150  2 => [
151  'pid' => 1300,
152  'uid' => 1330,
153  't3ver_oid' => 0,
154  't3ver_wsid' => 0,
155  't3ver_state' =>0,
156  'title' => 'EN: Board Games'
157  ],
158  1 => [
159  'pid' => 1000,
160  'uid' => 1300,
161  't3ver_oid' => 0,
162  't3ver_wsid' => 0,
163  't3ver_state' => 0,
164  'title' => 'EN: Products'
165  ],
166  0 => [
167  'pid' => 0,
168  'uid' => 1000,
169  't3ver_oid' => 0,
170  't3ver_wsid' => 0,
171  't3ver_state' => 0,
172  'title' => 'ACME Global'
173  ],
174  ];
175  self::assertSame($expected, $this->‪filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id', 'title']));
176  }
177 
182  {
183  $context = GeneralUtility::makeInstance(Context::class);
184  $context->setAspect('workspace', new WorkspaceAspect(1));
185  $subject = new RootlineUtility(1400, '', $context);
186  $result = $subject->get();
187 
188  $expected = [
189  1 => [
190  'pid' => 1000,
191  'uid' => 1400,
192  't3ver_oid' => 1400,
193  't3ver_wsid' => 1,
194  't3ver_state' => -1,
195  'title' => 'EN: A new page in workspace',
196  '_ORIG_pid' => 1000,
197  '_ORIG_uid' => 10002,
198  ],
199  0 => [
200  'pid' => 0,
201  'uid' => 1000,
202  't3ver_oid' => 1000,
203  't3ver_wsid' => 1,
204  't3ver_state' => 0,
205  'title' => 'ACME Global modified in Workspace 1',
206  '_ORIG_pid' => 0,
207  '_ORIG_uid' => 10000,
208  ],
209  ];
210  self::assertSame($expected, $this->‪filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id', 'title', '_ORIG_uid', '_ORIG_pid']));
211  // Now explicitly requesting the versioned ID, which DOES not hold the same information
212  // it explicitly removes the _ORIG_uid, and does not rewrite the uid
213  $subject = new RootlineUtility(10002, '', $context);
214  $result = $subject->get();
215  $expected[1]['uid'] = 10002;
216  unset($expected[1]['_ORIG_uid']);
217  self::assertSame($expected, $this->‪filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id', 'title', '_ORIG_uid', '_ORIG_pid']));
218  }
219 
223  public function ‪resolveLiveRootLineForMovedPage()
224  {
225  $context = GeneralUtility::makeInstance(Context::class);
226  $context->setAspect('workspace', new WorkspaceAspect(0));
227  $subject = new RootlineUtility(1333, '', $context);
228  $result = $subject->get();
229 
230  $expected = [
231  3 => [
232  'pid' => 1330,
233  'uid' => 1333,
234  't3ver_oid' => 0,
235  't3ver_wsid' => 0,
236  't3ver_state' => 0,
237  'title' => 'EN: Risk',
238  ],
239  2 => [
240  'pid' => 1300,
241  'uid' => 1330,
242  't3ver_oid' => 0,
243  't3ver_wsid' => 0,
244  't3ver_state' => 0,
245  'title' => 'EN: Board Games',
246  ],
247  1 => [
248  'pid' => 1000,
249  'uid' => 1300,
250  't3ver_oid' => 0,
251  't3ver_wsid' => 0,
252  't3ver_state' => 0,
253  'title' => 'EN: Products'
254  ],
255  0 => [
256  'pid' => 0,
257  'uid' => 1000,
258  't3ver_oid' => 0,
259  't3ver_wsid' => 0,
260  't3ver_state' => 0,
261  'title' => 'ACME Global',
262  ],
263  ];
264  self::assertSame($expected, $this->‪filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id', 'title', '_ORIG_uid', '_ORIG_pid']));
265  }
266 
271  {
272  $context = GeneralUtility::makeInstance(Context::class);
273  $context->setAspect('workspace', new WorkspaceAspect(1));
274  $subject = new RootlineUtility(1333, '', $context);
275  $result = $subject->get();
276 
277  $expected = [
278  3 => [
279  'pid' => 1320,
280  'uid' => 1333,
281  't3ver_oid' => 1333,
282  't3ver_wsid' => 1,
283  't3ver_state' => 4,
284  'title' => 'EN: Risk',
285  '_ORIG_pid' => 1330, // Pointing to the LIVE pid! WHY? All others point to the same PID!
286  '_ORIG_uid' => 10001,
287  ],
288  2 => [
289  'pid' => 1300,
290  'uid' => 1320,
291  't3ver_oid' => 0,
292  't3ver_wsid' => 0,
293  't3ver_state' => 0,
294  'title' => 'EN: Card Games',
295  ],
296  1 => [
297  'pid' => 1000,
298  'uid' => 1300,
299  't3ver_oid' => 0,
300  't3ver_wsid' => 0,
301  't3ver_state' => 0,
302  'title' => 'EN: Products'
303  ],
304  0 => [
305  'pid' => 0,
306  'uid' => 1000,
307  't3ver_oid' => 1000,
308  't3ver_wsid' => 1,
309  't3ver_state' => 0,
310  'title' => 'ACME Global modified in Workspace 1',
311  '_ORIG_pid' => 0,
312  '_ORIG_uid' => 10000,
313  ],
314  ];
315  self::assertSame($expected, $this->‪filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id', 'title', '_ORIG_uid', '_ORIG_pid']));
316 
317  // Now explicitly requesting the versioned ID, which holds the same result
318  $subject = new RootlineUtility(10001, '', $context);
319  $result = $subject->get();
320  self::assertSame($expected, $this->‪filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id', 'title', '_ORIG_uid', '_ORIG_pid']));
321 
322  // Now explicitly requesting the move placeholder, which gets resolved to the live ID, which holds the same result
323  $subject = new RootlineUtility(10004, '', $context);
324  $result = $subject->get();
325  self::assertSame($expected, $this->‪filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id', 'title', '_ORIG_uid', '_ORIG_pid']));
326  }
327 
332  {
333  self::expectException(PageNotFoundException::class);
334  self::expectExceptionCode(1343464101);
335  $context = GeneralUtility::makeInstance(Context::class);
336  $context->setAspect('workspace', new WorkspaceAspect(2));
337  $subject = new RootlineUtility(1310, '', $context);
338  $subject->get();
339  }
340 
341  protected function ‪filterExpectedValues(array $incomingData, array ‪$fields): array
342  {
343  $result = [];
344  foreach ($incomingData as $pos => $values) {
345  array_walk($values, function (&$val) {
346  if (is_numeric($val)) {
347  $val = (int)$val;
348  }
349  });
350  $result[$pos] = array_filter($values, function ($fieldName) use (‪$fields) {
351  return in_array($fieldName, ‪$fields, true);
352  }, ARRAY_FILTER_USE_KEY);
353  }
354  return $result;
355  }
356 }
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\resolveLiveRootLineForMovedPage
‪resolveLiveRootLineForMovedPage()
Definition: RootlineUtilityTest.php:221
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\resolveWorkspaceOverlaysOfNewPageInWorkspace
‪resolveWorkspaceOverlaysOfNewPageInWorkspace()
Definition: RootlineUtilityTest.php:179
‪TYPO3\CMS\Core\Context\WorkspaceAspect
Definition: WorkspaceAspect.php:31
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest
Definition: RootlineUtilityTest.php:35
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\LANGUAGE_PRESETS
‪const LANGUAGE_PRESETS
Definition: RootlineUtilityTest.php:37
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait
Definition: SiteBasedTestTrait.php:36
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildLanguageConfiguration
‪array buildLanguageConfiguration(string $identifier, string $base, array $fallbackIdentifiers=[], string $fallbackType=null)
Definition: SiteBasedTestTrait.php:142
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:58
‪TYPO3\CMS\Core\Utility\RootlineUtility
Definition: RootlineUtility.php:39
‪TYPO3\CMS\Core\Utility\RootlineUtility\purgeCaches
‪static purgeCaches()
Definition: RootlineUtility.php:160
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\rootlineFailsForDeletedParentPageInWorkspace
‪rootlineFailsForDeletedParentPageInWorkspace()
Definition: RootlineUtilityTest.php:329
‪$fields
‪$fields
Definition: pages.php:5
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:53
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\$coreExtensionsToLoad
‪string[] $coreExtensionsToLoad
Definition: RootlineUtilityTest.php:46
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪array buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:124
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\resolveWorkspaceOverlaysOfMovedPage
‪resolveWorkspaceOverlaysOfMovedPage()
Definition: RootlineUtilityTest.php:268
‪TYPO3\CMS\Core\Core\Bootstrap\initializeLanguageObject
‪static initializeLanguageObject()
Definition: Bootstrap.php:617
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\resolveLivePagesAndSkipWorkspacedVersions
‪resolveLivePagesAndSkipWorkspacedVersions()
Definition: RootlineUtilityTest.php:140
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\getForRootPageAndWithNonArrayTableColumnsTcaReturnsEmptyArray
‪getForRootPageAndWithNonArrayTableColumnsTcaReturnsEmptyArray()
Definition: RootlineUtilityTest.php:125
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\getForRootPageOnlyReturnsRootPageInformation
‪getForRootPageOnlyReturnsRootPageInformation()
Definition: RootlineUtilityTest.php:96
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\tearDownAfterClass
‪static tearDownAfterClass()
Definition: RootlineUtilityTest.php:73
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Tests\Functional\Utility
Definition: RootlineUtilityTest.php:18
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:66
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\setUp
‪setUp()
Definition: RootlineUtilityTest.php:48
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪array buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:109
‪TYPO3\CMS\Core\Exception\Page\PageNotFoundException
Definition: PageNotFoundException.php:24
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\filterExpectedValues
‪filterExpectedValues(array $incomingData, array $fields)
Definition: RootlineUtilityTest.php:339
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\setUpDatabase
‪setUpDatabase()
Definition: RootlineUtilityTest.php:80
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\setUpBeforeClass
‪static setUpBeforeClass()
Definition: RootlineUtilityTest.php:67
‪TYPO3\CMS\Core\Tests\Functional\Utility\RootlineUtilityTest\getForRootPageAndWithMissingTableColumnsTcaReturnsEmptyArray
‪getForRootPageAndWithMissingTableColumnsTcaReturnsEmptyArray()
Definition: RootlineUtilityTest.php:110