‪TYPO3CMS  11.5
MountPointTest.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 
21 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
22 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
23 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
24 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
25 
63 {
64  protected function ‪setUp(): void
65  {
66  parent::setUp();
67 
69  'main',
70  $this->‪buildSiteConfiguration(1000, 'https://acme.com/'),
71  [
72  $this->‪buildDefaultLanguageConfiguration('EN', '/'),
73  $this->‪buildLanguageConfiguration('FR', '/fr/', ['EN']),
74  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
75  ]
76  );
78  'acme-canada',
79  $this->‪buildSiteConfiguration(2000, 'https://acme.ca/'),
80  [
81  $this->‪buildDefaultLanguageConfiguration('EN', '/'),
82  $this->‪buildLanguageConfiguration('FR', '/fr/', ['EN']),
83  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
84  ]
85  );
87  'acme-us',
88  $this->‪buildSiteConfiguration(3000, 'https://acme.us/'),
89  [
90  $this->‪buildDefaultLanguageConfiguration('EN', '/'),
91  $this->‪buildLanguageConfiguration('ES', '/es/', ['ES']),
92  ]
93  );
95  'archive-acme-com',
96  $this->‪buildSiteConfiguration(10000, 'https://archive.acme.com/'),
97  [
98  $this->‪buildDefaultLanguageConfiguration('EN', '/'),
99  $this->‪buildLanguageConfiguration('FR', '/fr/', ['EN']),
100  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
101  ]
102  );
103  $this->withDatabaseSnapshot(function () {
104  $this->‪setUpDatabase();
105  });
106  }
107 
108  protected function ‪setUpDatabase(): void
109  {
110  $backendUser = $this->setUpBackendUserFromFixture(1);
112 
113  $scenarioFile = __DIR__ . '/Fixtures/MountPointScenario.yaml';
114  $factory = DataHandlerFactory::fromYamlFile($scenarioFile);
115  $writer = DataHandlerWriter::withBackendUser($backendUser);
116  $writer->invokeFactory($factory);
117  static::failIfArrayIsNotEmpty(
118  $writer->getErrors()
119  );
120 
121  $this->setUpFrontendRootPage(
122  1000,
123  [
124  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/LinkGenerator.typoscript',
125  ],
126  [
127  'title' => 'ACME Global',
128  ]
129  );
130  $this->setUpFrontendRootPage(
131  2000,
132  [
133  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/LinkGenerator.typoscript',
134  ],
135  [
136  'title' => 'ACME Canada',
137  ]
138  );
139  $this->setUpFrontendRootPage(
140  3000,
141  [
142  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/LinkGenerator.typoscript',
143  ],
144  [
145  'title' => 'ACME US',
146  ]
147  );
148  $this->setUpFrontendRootPage(
149  10000,
150  [
151  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/LinkGenerator.typoscript',
152  ],
153  [
154  'title' => 'ACME Archive',
155  ]
156  );
157  }
158 
163  {
164  $siteMapOfMainPage = [
165  ['title' => 'EN: Welcome', 'link' => '/welcome'],
166  [
167  'title' => 'EN: Features',
168  'link' => '/features',
169  'children' => [
170  [
171  'title' => 'EN: Frontend Editing',
172  'link' => '/features/frontend-editing/',
173  ],
174  ],
175  ],
176  [
177  'title' => 'EN: Products',
178  'link' => '/products',
179  'children' => [
180  [
181  'title' => 'EN: Toys',
182  'link' => '/products/toys',
183  ],
184  [
185  'title' => 'EN: Card Games',
186  'link' => '/products/card-games',
187  ],
188  [
189  'title' => 'EN: Board Games',
190  'link' => '/products/board-games',
191  'children' => [
192  [
193  'title' => 'EN: Monopoly',
194  'link' => '/products/monopoly',
195  ],
196  [
197  'title' => 'EN: Catan',
198  'link' => '/products/board-games/catan',
199  ],
200  [
201  'title' => 'EN: Risk',
202  'link' => '/risk',
203  ],
204  ],
205  ],
206  [
207  'title' => 'Archived Products',
208  'link' => '/products/archive',
209  'children' => [
210  [
211  'title' => 'EN: Games of the 1980s',
212  'link' => '/products/archive/games-of-the-1980s',
213  ],
214  [
215  'title' => 'EN: Games of the 1990s',
216  'link' => '/products/archive/games-of-the-1990s',
217  ],
218  [
219  'title' => 'Uno - The famous classic',
220  'link' => '/products/archive/uno',
221  ],
222  ],
223  ],
224  ],
225  ],
226  [
227  'title' => 'See our Archives',
228  'link' => '/archive',
229  'children' => [
230  [
231  'title' => 'EN: Archived Products',
232  'link' => '/archive/products',
233  'children' => [
234  [
235  'title' => 'EN: Games of the 1980s',
236  'link' => '/archive/products/games-of-the-1980s',
237  ],
238  [
239  'title' => 'EN: Games of the 1990s',
240  'link' => '/archive/products/games-of-the-1990s',
241  ],
242  [
243  'title' => 'Uno - The famous classic',
244  'link' => '/archive/uno',
245  ],
246  ],
247  ],
248  [
249  'title' => 'EN: Archived News',
250  'link' => '/archive/news',
251  'children' => [
252  [
253  'title' => 'EN: Whats new in 2020',
254  'link' => '/archive/news/latest-releases-2020',
255  ],
256  [
257  'title' => 'EN: Whats new in 2019',
258  'link' => '/archive/news/latest-releases-2019',
259  ],
260  ],
261  ],
262  ],
263  ],
264  ['title' => 'About us', 'link' => '/about'],
265  ['title' => 'Page not found', 'link' => '/404'],
266  // Link gets resolved to other site + shortcut to first page
267  ['title' => 'ACME in Canada', 'link' => 'https://acme.ca/news/'],
268  ];
269  $siteMapOfCanadianPage = [
270  [
271  'title' => 'News of Canada',
272  'link' => '/news/',
273  'children' => [
274  [
275  'title' => 'New Games in Canada 2020',
276  'link' => '/news/games-in-canada-2020',
277  ],
278  [
279  'title' => 'New Games in Canada 2019',
280  'link' => '/slug-with-a-mistake-which-never-changed/games-in-canada-2019',
281  ],
282  ],
283  ],
284  [
285  'title' => 'Products',
286  'link' => '/products',
287  'children' => [
288  [
289  'title' => 'EN: Toys',
290  'link' => '/products/toys',
291  ],
292  [
293  'title' => 'EN: Card Games',
294  'link' => '/products/card-games',
295  ],
296  [
297  'title' => 'EN: Board Games',
298  'link' => '/products/board-games',
299  'children' => [
300  [
301  'title' => 'EN: Monopoly',
302  'link' => '/products/monopoly',
303  ],
304  [
305  'title' => 'EN: Catan',
306  'link' => '/products/board-games/catan',
307  ],
308  [
309  'title' => 'EN: Risk',
310  'link' => '/products/risk',
311  ],
312  ],
313  ],
314  [
315  'title' => 'Archived Products',
316  'link' => '/products/archive',
317  'children' => [
318  [
319  'title' => 'EN: Games of the 1980s',
320  'link' => '/products/archive/games-of-the-1980s',
321  ],
322  [
323  'title' => 'EN: Games of the 1990s',
324  'link' => '/products/archive/games-of-the-1990s',
325  ],
326  [
327  'title' => 'Uno - The famous classic',
328  // Perfect example that the first two slugs are the slugs from the MountPoint Pages
329  'link' => '/products/archive/uno',
330  ],
331  ],
332  ],
333  ],
334  ],
335  [
336  'title' => 'All News',
337  'link' => '/all-news',
338  'children' => [
339  [
340  'title' => 'News of Canada',
341  // slash is added because ID 2100 has a trailing slash
342  'link' => '/all-news/canada/',
343  'children' => [
344  [
345  'title' => 'New Games in Canada 2020',
346  // Example where the slug of the MountPoint page is added
347  // And the "common" prefix of the mounted page - "/news" is removed
348  // Frmo the slug of the main page
349  'link' => '/all-news/canada/games-in-canada-2020',
350  ],
351  [
352  'title' => 'New Games in Canada 2019',
353  // no common prefix, but the original slug was added
354  'link' => '/all-news/canada/slug-with-a-mistake-which-never-changed/games-in-canada-2019',
355  ],
356  ],
357  ],
358  [
359  'title' => 'Archived News',
360  'link' => '/all-news/archive',
361  'children' => [
362  [
363  'title' => 'EN: Whats new in 2020',
364  'link' => '/all-news/archive/latest-releases-2020',
365  ],
366  [
367  'title' => 'EN: Whats new in 2019',
368  'link' => '/all-news/archive/latest-releases-2019',
369  ],
370  ],
371  ],
372  ],
373  ],
374  ['title' => 'Link To Our Worldwide Site', 'link' => 'https://acme.com/welcome'],
375  ];
376  return [
377  'ACME Global' => [
378  'https://acme.com/welcome',
379  $siteMapOfMainPage,
380  ],
381  'ACME Canada First Subpage in EN' => [
382  'https://acme.ca/all-news',
383  $siteMapOfCanadianPage,
384  ],
385  'ACME Canada Subpage of mounted Products page' => [
386  'https://acme.ca/products/risk',
387  $siteMapOfCanadianPage,
388  ],
389  ];
390  }
391 
399  public function ‪hierarchicalMenuIsGenerated(string $accessedUrl, array $expectation): void
400  {
401  $response = $this->executeFrontendSubRequest(
402  (new InternalRequest($accessedUrl))
403  ->withInstructions([
405  'levels' => 3,
406  'entryLevel' => 0,
407  'expandAll' => 1,
408  'includeSpacer' => 1,
409  'titleField' => 'title',
410  ]),
411  ])
412  );
413 
414  $json = json_decode((string)$response->getBody(), true);
415  $json = $this->‪filterMenu($json);
416 
417  self::assertSame($expectation, $json);
418  }
419 
421  {
422  return [
423  'regular page on global site' => [
424  'https://acme.com/welcome',
425  1000,
426  1100,
427  null,
428  ],
429  'mountpoint to a different site with same slug on global site' => [
430  'https://acme.com/products/archive',
431  1000,
432  1340,
433  '10100-1340',
434  ],
435  'subpage of mountpoint to a different site with same slug on global site' => [
436  'https://acme.com/products/archive/uno',
437  1000,
438  10130,
439  '10100-1340',
440  ],
441  'subpage of mountpoint to a different site on global site' => [
442  'https://acme.com/archive/products/games-of-the-1980s',
443  1000,
444  10110,
445  '10000-1400',
446  ],
447  ];
448  }
449 
458  public function ‪requestsResolvePageIdAndMountPointParameter(string $uri, int $rootPageId, int $expectedPageId, ?string $expectedMountPointParameter): void
459  {
460  $this->setUpFrontendRootPage(
461  $rootPageId,
462  [
463  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/LinkRequest.typoscript',
464  ],
465  [
466  'title' => 'ACME Root',
467  ]
468  );
469  $response = $this->executeFrontendSubRequest((new InternalRequest($uri)));
470  $responseData = json_decode((string)$response->getBody(), true);
471  self::assertSame(200, $response->getStatusCode());
472  self::assertSame($expectedPageId, $responseData['pageId']);
473  self::assertSame($expectedMountPointParameter, $responseData['dynamicArguments']['MP'] ?? null);
474  }
475 
480  {
481  return [
482  'Show content of MountPoint Page' => [
483  'https://acme.ca/all-news/archive',
484  'Content of MountPoint Page',
485  ],
486  'Show content of Mounted Page' => [
487  'https://acme.ca/all-news/canada',
488  'See a list of all games distributed in canada',
489  ],
490  'Show content of Mounted Page for second site' => [
491  'https://acme.us/all-news/us',
492  'See a list of all games distributed in the US',
493  ],
494  ];
495  }
496 
507  public function ‪mountPointPagesShowContentAsConfigured(string $uri, string $expected): void
508  {
509  $this->setUpFrontendRootPage(
510  2000,
511  [
512  'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
513  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
514  ],
515  [
516  'title' => 'ACME Root',
517  ]
518  );
519  $this->setUpFrontendRootPage(
520  3000,
521  [
522  'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
523  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
524  ],
525  [
526  'title' => 'ACME Root',
527  ]
528  );
529  $response = $this->executeFrontendSubRequest((new InternalRequest($uri)));
530  self::assertSame(200, $response->getStatusCode());
531  $responseStructure = ResponseContent::fromString(
532  (string)$response->getBody()
533  );
534  $responseRecords = $responseStructure->getSection('Default')->getRecords();
535  $firstContent = null;
536  // Find tt_content element
537  foreach ($responseRecords as $identifier => $record) {
538  if (strpos($identifier, 'tt_content:') === 0) {
539  $firstContent = $record;
540  break;
541  }
542  }
543  if ($expected) {
544  self::assertStringContainsString($expected, $firstContent['header'] ?? '');
545  } else {
546  self::assertEmpty($firstContent);
547  }
548  }
549 }
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\hierarchicalMenuIsGeneratedDataProvider
‪array hierarchicalMenuIsGeneratedDataProvider()
Definition: MountPointTest.php:162
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\hierarchicalMenuIsGenerated
‪hierarchicalMenuIsGenerated(string $accessedUrl, array $expectation)
Definition: MountPointTest.php:399
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase\filterMenu
‪array filterMenu(array $menu, array $keepNames=['title', 'link'])
Definition: AbstractTestCase.php:195
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildLanguageConfiguration
‪array buildLanguageConfiguration(string $identifier, string $base, array $fallbackIdentifiers=[], string $fallbackType=null)
Definition: SiteBasedTestTrait.php:144
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\setUpDatabase
‪setUpDatabase()
Definition: MountPointTest.php:108
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:58
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase
Definition: AbstractTestCase.php:29
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase\createHierarchicalMenuProcessorInstruction
‪ArrayValueInstruction createHierarchicalMenuProcessorInstruction(array $typoScript)
Definition: AbstractTestCase.php:148
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\mountPointPagesShowContentAsConfigured
‪mountPointPagesShowContentAsConfigured(string $uri, string $expected)
Definition: MountPointTest.php:507
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest
Definition: MountPointTest.php:63
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\setUp
‪setUp()
Definition: MountPointTest.php:64
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪array buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:126
‪TYPO3\CMS\Core\Core\Bootstrap\initializeLanguageObject
‪static initializeLanguageObject()
Definition: Bootstrap.php:598
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling
Definition: AbstractTestCase.php:18
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\requestsResolvePageIdAndMountPointParameter
‪requestsResolvePageIdAndMountPointParameter(string $uri, int $rootPageId, int $expectedPageId, ?string $expectedMountPointParameter)
Definition: MountPointTest.php:458
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:70
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪array buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:111
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\requestsResolvePageIdAndMountPointParameterDataProvider
‪requestsResolvePageIdAndMountPointParameterDataProvider()
Definition: MountPointTest.php:420
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\MountPointTest\mountPointPagesShowContentAsConfiguredDataProvider
‪array mountPointPagesShowContentAsConfiguredDataProvider()
Definition: MountPointTest.php:479