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