[TASK] Move Page Title generation to TSFE
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / Page / PageGeneratorTest.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
17 use Prophecy\Argument;
18 use TYPO3\CMS\Core\Page\PageRenderer;
19 use TYPO3\CMS\Core\TypoScript\TemplateService;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
22 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
23 use TYPO3\CMS\Frontend\Page\PageGenerator;
24
25 /**
26 * Test case
27 */
28 class PageGeneratorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
29 {
30 /**
31 * @var array A backup of registered singleton instances
32 */
33 protected $singletonInstances = [];
34
35 protected function setUp()
36 {
37 $this->singletonInstances = GeneralUtility::getSingletonInstances();
38 }
39
40 protected function tearDown()
41 {
42 GeneralUtility::purgeInstances();
43 GeneralUtility::resetSingletonInstances($this->singletonInstances);
44 parent::tearDown();
45 }
46
47 /**
48 * @return array
49 */
50 public function generateMetaTagHtmlGeneratesCorrectTagsDataProvider()
51 {
52 return [
53 'simple meta' => [
54 [
55 'author' => 'Markus Klein',
56 ],
57 '',
58 [
59 'type' => 'name',
60 'name' => 'author',
61 'content' => 'Markus Klein'
62 ]
63 ],
64 'httpEquivalent meta' => [
65 [
66 'X-UA-Compatible' => 'IE=edge,chrome=1',
67 'X-UA-Compatible.' => ['httpEquivalent' => 1]
68 ],
69 'IE=edge,chrome=1',
70 [
71 'type' => 'http-equiv',
72 'name' => 'X-UA-Compatible',
73 'content' => 'IE=edge,chrome=1'
74 ]
75 ],
76 'httpEquivalent meta xhtml new notation' => [
77 [
78 'X-UA-Compatible' => 'IE=edge,chrome=1',
79 'X-UA-Compatible.' => ['attribute' => 'http-equiv']
80 ],
81 'IE=edge,chrome=1',
82 [
83 'type' => 'http-equiv',
84 'name' => 'X-UA-Compatible',
85 'content' => 'IE=edge,chrome=1'
86 ]
87 ],
88 'refresh meta' => [
89 [
90 'refresh' => '10',
91 ],
92 '',
93 [
94 'type' => 'http-equiv',
95 'name' => 'refresh',
96 'content' => '10'
97 ]
98 ],
99 'refresh meta new notation' => [
100 [
101 'refresh' => '10',
102 'refresh.' => ['attribute' => 'http-equiv']
103 ],
104 '10',
105 [
106 'type' => 'http-equiv',
107 'name' => 'refresh',
108 'content' => '10'
109 ]
110 ],
111 'meta with dot' => [
112 [
113 'DC.author' => 'Markus Klein',
114 ],
115 '',
116 [
117 'type' => 'name',
118 'name' => 'DC.author',
119 'content' => 'Markus Klein'
120 ]
121 ],
122 'meta with colon' => [
123 [
124 'OG:title' => 'Magic Tests',
125 ],
126 '',
127 [
128 'type' => 'name',
129 'name' => 'OG:title',
130 'content' => 'Magic Tests'
131 ]
132 ],
133 'different attribute name' => [
134 [
135 'og:site_title' => 'My TYPO3 site',
136 'og:site_title.' => ['attribute' => 'property'],
137 ],
138 'My TYPO3 site',
139 [
140 'type' => 'property',
141 'name' => 'og:site_title',
142 'content' => 'My TYPO3 site'
143 ]
144 ],
145 'meta with 0 value' => [
146 [
147 'custom:key' => '0',
148 ],
149 '',
150 [
151 'type' => 'name',
152 'name' => 'custom:key',
153 'content' => '0'
154 ]
155 ],
156 ];
157 }
158
159 /**
160 * @test
161 */
162 public function generateMetaTagExpectExceptionOnBogusTags()
163 {
164 $stdWrapResult = '10';
165
166 $typoScript = [
167 'refresh' => '10',
168 'refresh.' => ['attribute' => 'http-equiv-new']
169 ];
170
171 $expectedTags = [
172 'type' => 'http-equiv-new',
173 'name' => 'refresh',
174 'content' => '10'
175 ];
176
177 $cObj = $this->prophesize(ContentObjectRenderer::class);
178 $cObj->cObjGet(Argument::cetera())->shouldBeCalled();
179 $cObj->stdWrap(Argument::cetera())->willReturn($stdWrapResult);
180 $tmpl = $this->prophesize(TemplateService::class);
181 $tsfe = $this->prophesize(TypoScriptFrontendController::class);
182 $tsfe->generatePageTitle()->willReturn('');
183 $tsfe->INTincScript_loadJSCode()->shouldBeCalled();
184 $tsfe->cObj = $cObj->reveal();
185 $tsfe->tmpl = $tmpl->reveal();
186 $tsfe->page = [
187 'title' => ''
188 ];
189 $tsfe->pSetup = [
190 'meta.' => $typoScript
191 ];
192 $GLOBALS['TSFE'] = $tsfe->reveal();
193
194 $pageRendererProphecy = $this->prophesize(PageRenderer::class);
195 GeneralUtility::setSingletonInstance(PageRenderer::class, $pageRendererProphecy->reveal());
196
197 PageGenerator::renderContentWithHeader('');
198
199 $pageRendererProphecy->setMetaTag($expectedTags['type'], $expectedTags['name'], $expectedTags['content'])->willThrow(\InvalidArgumentException::class);
200 }
201
202 /**
203 * @test
204 * @dataProvider generateMetaTagHtmlGeneratesCorrectTagsDataProvider
205 *
206 * @param array $typoScript
207 * @param string $stdWrapResult
208 * @param array $expectedTags
209 */
210 public function generateMetaTagHtmlGeneratesCorrectTags(array $typoScript, string $stdWrapResult, array $expectedTags)
211 {
212 $cObj = $this->prophesize(ContentObjectRenderer::class);
213 $cObj->cObjGet(Argument::cetera())->shouldBeCalled();
214 $cObj->stdWrap(Argument::cetera())->willReturn($stdWrapResult);
215 $tmpl = $this->prophesize(TemplateService::class);
216 $tsfe = $this->prophesize(TypoScriptFrontendController::class);
217 $tsfe->generatePageTitle()->willReturn('');
218 $tsfe->INTincScript_loadJSCode()->shouldBeCalled();
219 $tsfe->cObj = $cObj->reveal();
220 $tsfe->tmpl = $tmpl->reveal();
221 $tsfe->config['config'] = [];
222 $tsfe->page = [
223 'title' => ''
224 ];
225 $tsfe->pSetup = [
226 'meta.' => $typoScript
227 ];
228 $GLOBALS['TSFE'] = $tsfe->reveal();
229
230 $pageRendererProphecy = $this->prophesize(PageRenderer::class);
231 GeneralUtility::setSingletonInstance(PageRenderer::class, $pageRendererProphecy->reveal());
232
233 PageGenerator::renderContentWithHeader('');
234
235 $pageRendererProphecy->setMetaTag($expectedTags['type'], $expectedTags['name'], $expectedTags['content'])->shouldHaveBeenCalled();
236 }
237
238 /**
239 * @test
240 */
241 public function generateMetaTagHtmlGenerateNoTagWithEmptyContent()
242 {
243 $stdWrapResult = '';
244
245 $typoScript = [
246 'custom:key' => '',
247 ];
248
249 $cObj = $this->prophesize(ContentObjectRenderer::class);
250 $cObj->cObjGet(Argument::cetera())->shouldBeCalled();
251 $cObj->stdWrap(Argument::cetera())->willReturn($stdWrapResult);
252 $tmpl = $this->prophesize(TemplateService::class);
253 $tsfe = $this->prophesize(TypoScriptFrontendController::class);
254 $tsfe->generatePageTitle()->willReturn('');
255 $tsfe->INTincScript_loadJSCode()->shouldBeCalled();
256 $tsfe->cObj = $cObj->reveal();
257 $tsfe->tmpl = $tmpl->reveal();
258 $tsfe->config['config'] = [];
259 $tsfe->page = [
260 'title' => ''
261 ];
262 $tsfe->pSetup = [
263 'meta.' => $typoScript
264 ];
265 $GLOBALS['TSFE'] = $tsfe->reveal();
266
267 $pageRendererProphecy = $this->prophesize(PageRenderer::class);
268 GeneralUtility::setSingletonInstance(PageRenderer::class, $pageRendererProphecy->reveal());
269
270 PageGenerator::renderContentWithHeader('');
271
272 $pageRendererProphecy->setMetaTag(null, null, null)->shouldNotBeCalled();
273 }
274
275 public function generateMultipleMetaTagsDataProvider()
276 {
277 return [
278 'multi value attribute name' => [
279 [
280 'og:locale:alternate.' => [
281 'attribute' => 'property',
282 'value' => [
283 10 => 'nl_NL',
284 20 => 'de_DE',
285 ]
286 ],
287 ],
288 '',
289 [
290 [
291 'type' => 'property',
292 'name' => 'og:locale:alternate',
293 'content' => 'nl_NL'
294 ],
295 [
296 'type' => 'property',
297 'name' => 'og:locale:alternate',
298 'content' => 'de_DE'
299 ]
300 ]
301 ],
302 'multi value attribute name (empty values are skipped)' => [
303 [
304 'og:locale:alternate.' => [
305 'attribute' => 'property',
306 'value' => [
307 10 => 'nl_NL',
308 20 => '',
309 30 => 'de_DE',
310 ]
311 ],
312 ],
313 '',
314 [
315 [
316 'type' => 'property',
317 'name' => 'og:locale:alternate',
318 'content' => 'nl_NL'
319 ],
320 [
321 'type' => 'property',
322 'name' => 'og:locale:alternate',
323 'content' => 'de_DE'
324 ]
325 ],
326 ],
327 ];
328 }
329
330 /**
331 * @test
332 * @dataProvider generateMultipleMetaTagsDataProvider
333 *
334 * @param array $typoScript
335 * @param string $stdWrapResult
336 * @param array $expectedTags
337 */
338 public function generateMultipleMetaTags(array $typoScript, string $stdWrapResult, array $expectedTags)
339 {
340 $cObj = $this->prophesize(ContentObjectRenderer::class);
341 $cObj->cObjGet(Argument::cetera())->shouldBeCalled();
342 $cObj->stdWrap(Argument::cetera())->willReturn($stdWrapResult);
343 $tmpl = $this->prophesize(TemplateService::class);
344 $tsfe = $this->prophesize(TypoScriptFrontendController::class);
345 $tsfe->generatePageTitle()->willReturn('');
346 $tsfe->INTincScript_loadJSCode()->shouldBeCalled();
347 $tsfe->cObj = $cObj->reveal();
348 $tsfe->tmpl = $tmpl->reveal();
349 $tsfe->config['config'] = [];
350 $tsfe->page = [
351 'title' => ''
352 ];
353 $tsfe->pSetup = [
354 'meta.' => $typoScript
355 ];
356 $GLOBALS['TSFE'] = $tsfe->reveal();
357
358 $pageRendererProphecy = $this->prophesize(PageRenderer::class);
359 GeneralUtility::setSingletonInstance(PageRenderer::class, $pageRendererProphecy->reveal());
360
361 PageGenerator::renderContentWithHeader('');
362
363 $pageRendererProphecy->setMetaTag($expectedTags[0]['type'], $expectedTags[0]['name'], $expectedTags[0]['content'])->shouldHaveBeenCalled();
364 $pageRendererProphecy->setMetaTag($expectedTags[1]['type'], $expectedTags[1]['name'], $expectedTags[1]['content'])->shouldHaveBeenCalled();
365 }
366 }