[TASK] Add unit tests for HtmlParser->removeFirstAndLastTag()
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Html / HtmlParserTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Html;
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 TYPO3\CMS\Core\Html\HtmlParser;
18
19 /**
20 * Testcase for \TYPO3\CMS\Core\Html\HtmlParser
21 */
22 class HtmlParserTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
23
24 /**
25 * @var \TYPO3\CMS\Core\Html\HtmlParser
26 */
27 protected $subject = NULL;
28
29 protected function setUp() {
30 $this->subject = new HtmlParser();
31 }
32
33 /**
34 * Data provider for getSubpart
35 *
36 * @return array
37 */
38 public function getSubpartDataProvider() {
39 return array(
40 'No start marker' => array(
41 '<body>text</body>',
42 '###SUBPART###',
43 ''
44 ),
45 'No stop marker' => array(
46 '<body>
47 <!-- ###SUBPART### Start -->
48 text
49 </body>',
50 '###SUBPART###',
51 ''
52 ),
53 'Start and stop marker in HTML comment' => array(
54 '<body>
55 <!-- ###SUBPART### Start -->
56 text
57 <!-- ###SUBPART### End -->
58 </body>',
59 '###SUBPART###',
60 '
61 text
62 '
63 ),
64 'Stop marker in HTML comment' => array(
65 '<body>
66 ###SUBPART###
67 text
68 <!-- ###SUBPART### End -->
69 </body>',
70 '###SUBPART###',
71 '
72 text
73 '
74 ),
75 'Start marker in HTML comment' => array(
76 '<body>
77 <!-- ###SUBPART### Start -->
78 text
79 ###SUBPART###
80 </body>',
81 '###SUBPART###',
82 '
83 text
84 '
85 ),
86 'Start and stop marker direct' => array(
87 '<body>
88 ###SUBPART###
89 text
90 ###SUBPART###
91 </body>',
92 '###SUBPART###',
93 '
94 text
95 '
96 ),
97 );
98 }
99
100 /**
101 * @test
102 * @param string $content
103 * @param string $marker
104 * @param string $expected
105 * @dataProvider getSubpartDataProvider
106 */
107 public function getSubpart($content, $marker, $expected) {
108 $this->assertSame($expected, HtmlParser::getSubpart($content, $marker));
109 }
110
111 /**
112 * Data provider for substituteSubpart
113 *
114 * @return array
115 */
116 public function substituteSubpartDataProvider() {
117 return array(
118 'No start marker' => array(
119 '<body>text</body>',
120 '###SUBPART###',
121 'hello',
122 FALSE,
123 FALSE,
124 '<body>text</body>'
125 ),
126 'No stop marker' => array(
127 '<body>
128 <!-- ###SUBPART### Start -->
129 text
130 </body>',
131 '###SUBPART###',
132 'hello',
133 FALSE,
134 FALSE,
135 '<body>
136 <!-- ###SUBPART### Start -->
137 text
138 </body>',
139 ),
140 'Start and stop marker in HTML comment' => array(
141 '<body>
142 <!-- ###SUBPART### Start -->
143 text
144 <!-- ###SUBPART### End -->
145 </body>',
146 '###SUBPART###',
147 'hello',
148 FALSE,
149 FALSE,
150 '<body>
151 hello
152 </body>'
153 ),
154 'Recursive subpart' => array(
155 '<body>
156 <!-- ###SUBPART### Start -->text1<!-- ###SUBPART### End -->
157 <!-- ###SUBPART### Start -->text2<!-- ###SUBPART### End -->
158 </body>',
159 '###SUBPART###',
160 'hello',
161 TRUE,
162 FALSE,
163 '<body>
164 hello
165 hello
166 </body>'
167 ),
168 'Keep HTML marker' => array(
169 '<body>
170 <!-- ###SUBPART### Start -->text<!-- ###SUBPART### End -->
171 </body>',
172 '###SUBPART###',
173 'hello',
174 FALSE,
175 TRUE,
176 '<body>
177 <!-- ###SUBPART### Start -->hello<!-- ###SUBPART### End -->
178 </body>'
179 ),
180 'Keep HTML begin marker' => array(
181 '<body>
182 <!-- ###SUBPART### Start -->text###SUBPART###
183 </body>',
184 '###SUBPART###',
185 'hello',
186 FALSE,
187 TRUE,
188 '<body>
189 <!-- ###SUBPART### Start -->hello###SUBPART###
190 </body>'
191 ),
192 'Keep HTML end marker' => array(
193 '<body>
194 ###SUBPART###text<!-- ###SUBPART### End -->
195 </body>',
196 '###SUBPART###',
197 'hello',
198 FALSE,
199 TRUE,
200 '<body>
201 ###SUBPART###hello<!-- ###SUBPART### End -->
202 </body>'
203 ),
204 'Keep plain marker' => array(
205 '<body>
206 ###SUBPART###text###SUBPART###
207 </body>',
208 '###SUBPART###',
209 'hello',
210 FALSE,
211 TRUE,
212 '<body>
213 ###SUBPART###hello###SUBPART###
214 </body>'
215 ),
216 'Wrap around' => array(
217 '<body>
218 ###SUBPART###text###SUBPART###
219 </body>',
220 '###SUBPART###',
221 array('before-', '-after'),
222 FALSE,
223 TRUE,
224 '<body>
225 ###SUBPART###before-text-after###SUBPART###
226 </body>'
227 ),
228 );
229 }
230
231 /**
232 * @test
233 * @param string $content
234 * @param string $marker
235 * @param array $subpartContent
236 * @param bool $recursive
237 * @param bool $keepMarker
238 * @param string $expected
239 * @dataProvider substituteSubpartDataProvider
240 */
241 public function substituteSubpart($content, $marker, $subpartContent, $recursive, $keepMarker, $expected) {
242 $this->assertSame($expected, HtmlParser::substituteSubpart($content, $marker, $subpartContent, $recursive, $keepMarker));
243 }
244
245 /**
246 * Data provider for substituteMarkerArray
247 */
248 public function substituteMarkerArrayDataProvider() {
249 return array(
250 'Upper case marker' => array(
251 'This is ###MARKER1### and this is ###MARKER2###',
252 array('###MARKER1###' => 'marker 1',
253 '###MARKER2###' => 'marker 2'),
254 '',
255 FALSE,
256 FALSE,
257 'This is marker 1 and this is marker 2'
258 ),
259 'Lower case marker' => array(
260 'This is ###MARKER1### and this is ###MARKER2###',
261 array('###marker1###' => 'marker 1',
262 '###marker2###' => 'marker 2'),
263 '',
264 TRUE,
265 FALSE,
266 'This is marker 1 and this is marker 2'
267 ),
268 'Upper case marker without hash mark' => array(
269 'This is ###MARKER1### and this is ###MARKER2###',
270 array('MARKER1' => 'marker 1',
271 'MARKER2' => 'marker 2'),
272 '###|###',
273 FALSE,
274 FALSE,
275 'This is marker 1 and this is marker 2'
276 ),
277 'Upper case marker with another hash mark' => array(
278 'This is *MARKER1* and this is *MARKER2*',
279 array('MARKER1' => 'marker 1',
280 'MARKER2' => 'marker 2'),
281 '*|*',
282 FALSE,
283 FALSE,
284 'This is marker 1 and this is marker 2'
285 ),
286 'Upper case marker with unused marker' => array(
287 'This is ###MARKER1### and this is ###MARKER2### ###UNUSED###',
288 array('###MARKER1###' => 'marker 1',
289 '###MARKER2###' => 'marker 2'),
290 '',
291 FALSE,
292 FALSE,
293 'This is marker 1 and this is marker 2 ###UNUSED###'
294 ),
295 'Upper case marker with unused marker deleted' => array(
296 'This is ###MARKER1### and this is ###MARKER2### ###UNUSED###',
297 array('###MARKER1###' => 'marker 1',
298 '###MARKER2###' => 'marker 2'),
299 '',
300 FALSE,
301 TRUE,
302 'This is marker 1 and this is marker 2 '
303 ),
304 );
305 }
306
307 /**
308 * @test
309 * @dataProvider substituteMarkerArrayDataProvider
310 * @param string $content The content stream, typically HTML template content.
311 * @param array $markContentArray The array of key/value pairs being marker/content values used in the substitution. For each element in this array the function will substitute a marker in the content stream with the content.
312 * @param string $wrap A wrap value - [part 1] | [part 2] - for the markers before substitution
313 * @param bool $uppercase If set, all marker string substitution is done with upper-case markers.
314 * @param bool $deleteUnused If set, all unused marker are deleted.
315 */
316 public function substituteMarkerArray($content, $markContentArray, $wrap, $uppercase, $deleteUnused, $expected) {
317 $this->assertSame($expected, HtmlParser::substituteMarkerArray($content, $markContentArray, $wrap, $uppercase, $deleteUnused));
318 }
319
320 /**
321 * Data provider for substituteMarker
322 */
323 public function substituteMarkerDataProvider() {
324 return array(
325 'Single marker' => array(
326 'This is a ###SAMPLE### text',
327 '###SAMPLE###',
328 'simple',
329 'This is a simple text'
330 ),
331 'Double marker' => array(
332 'This is a ###SAMPLE### text with a ###SAMPLE### content',
333 '###SAMPLE###',
334 'simple',
335 'This is a simple text with a simple content'
336 ),
337 );
338 }
339
340 /**
341 * @dataProvider substituteMarkerDataProvider
342 * @param string $content The content stream, typically HTML template content.
343 * @param string $marker The marker string, typically on the form "###[the marker string]###
344 * @param mixed $markContent The content to insert instead of the marker string found.
345 * @param string $expected The expected result of the substitution
346 */
347 public function substituteMarker($content, $marker, $markContent, $expected) {
348 $this->assertSame($expected, HtmlParser::substituteMarker($content, $marker, $markContent));
349 }
350
351 /**
352 * Data provider for substituteSubpartArray
353 *
354 * @return array
355 */
356 public function substituteSubpartArrayDataProvider() {
357 return array(
358 'Substitute multiple subparts at once with plain marker' => array(
359 '<body>
360 ###SUBPART1###text1###SUBPART1###
361 ###SUBPART2###text2###SUBPART2###
362 </body>',
363 array ('###SUBPART1###' => 'hello',
364 '###SUBPART2###' => 'world'),
365 '<body>
366 hello
367 world
368 </body>'
369 ),
370 );
371 }
372
373 /**
374 * @test
375 * @param string $content
376 * @param array $subpartsContent
377 * @param string $expected
378 * @dataProvider substituteSubpartArrayDataProvider
379 */
380 public function substituteSubpartArray($content, array $subpartsContent, $expected) {
381 $this->assertSame($expected, HtmlParser::substituteSubpartArray($content, $subpartsContent));
382 }
383
384 /**
385 * Data provider for substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArray
386 *
387 * @return array
388 */
389 public function substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArrayDataProvider() {
390 $template = '###SINGLEMARKER1###
391 <!-- ###FOO### begin -->
392 <!-- ###BAR### begin -->
393 ###SINGLEMARKER2###
394 <!-- ###BAR### end -->
395 <!-- ###FOOTER### begin -->
396 ###SINGLEMARKER3###
397 <!-- ###FOOTER### end -->
398 <!-- ###FOO### end -->';
399
400 $expected ='Value 1
401
402
403 Value 2.1
404
405 Value 2.2
406
407
408 Value 3.1
409
410 Value 3.2
411
412 ';
413
414 return array(
415 'Single marker' => array(
416 '###SINGLEMARKER###',
417 array(
418 '###SINGLEMARKER###' => 'Value 1'
419 ),
420 '',
421 FALSE,
422 FALSE,
423 'Value 1'
424 ),
425 'Subpart marker' => array(
426 $template,
427 array(
428 '###SINGLEMARKER1###' => 'Value 1',
429 '###FOO###' => array(
430 array(
431 '###BAR###' => array(
432 array(
433 '###SINGLEMARKER2###' => 'Value 2.1'
434 ),
435 array(
436 '###SINGLEMARKER2###' => 'Value 2.2'
437 )
438 ),
439 '###FOOTER###' => array(
440 array(
441 '###SINGLEMARKER3###' => 'Value 3.1'
442 ),
443 array(
444 '###SINGLEMARKER3###' => 'Value 3.2'
445 )
446 )
447 )
448 )
449 ),
450 '',
451 FALSE,
452 FALSE,
453 $expected
454 ),
455 'Subpart marker with wrap' => array(
456 $template,
457 array(
458 'SINGLEMARKER1' => 'Value 1',
459 'FOO' => array(
460 array(
461 'BAR' => array(
462 array(
463 'SINGLEMARKER2' => 'Value 2.1'
464 ),
465 array(
466 'SINGLEMARKER2' => 'Value 2.2'
467 )
468 ),
469 'FOOTER' => array(
470 array(
471 'SINGLEMARKER3' => 'Value 3.1'
472 ),
473 array(
474 'SINGLEMARKER3' => 'Value 3.2'
475 )
476 )
477 )
478 )
479 ),
480 '###|###',
481 FALSE,
482 FALSE,
483 $expected
484 ),
485 'Subpart marker with lower marker array keys' => array(
486 $template,
487 array(
488 '###singlemarker1###' => 'Value 1',
489 '###foo###' => array(
490 array(
491 '###bar###' => array(
492 array(
493 '###singlemarker2###' => 'Value 2.1'
494 ),
495 array(
496 '###singlemarker2###' => 'Value 2.2'
497 )
498 ),
499 '###footer###' => array(
500 array(
501 '###singlemarker3###' => 'Value 3.1'
502 ),
503 array(
504 '###singlemarker3###' => 'Value 3.2'
505 )
506 )
507 )
508 )
509 ),
510 '',
511 TRUE,
512 FALSE,
513 $expected
514 ),
515 'Subpart marker with unused markers' => array(
516 $template,
517 array(
518 '###FOO###' => array(
519 array(
520 '###BAR###' => array(
521 array(
522 '###SINGLEMARKER2###' => 'Value 2.1'
523 )
524 ),
525 '###FOOTER###' => array(
526 array(
527 '###SINGLEMARKER3###' => 'Value 3.1'
528 )
529 )
530 )
531 )
532 ),
533 '',
534 FALSE,
535 TRUE,
536 '
537
538
539 Value 2.1
540
541
542 Value 3.1
543
544 '
545 ),
546 'Subpart marker with empty subpart' => array(
547 $template,
548 array(
549 '###SINGLEMARKER1###' => 'Value 1',
550 '###FOO###' => array(
551 array(
552 '###BAR###' => array(
553 array(
554 '###SINGLEMARKER2###' => 'Value 2.1'
555 ),
556 array(
557 '###SINGLEMARKER2###' => 'Value 2.2'
558 )
559 ),
560 '###FOOTER###' => array()
561 )
562 )
563 ),
564 '',
565 FALSE,
566 FALSE,
567 'Value 1
568
569
570 Value 2.1
571
572 Value 2.2
573
574
575 '
576 )
577 );
578 }
579
580 /**
581 * @test
582 * @param string $template
583 * @param array $markersAndSubparts
584 * @param string $wrap
585 * @param bool $uppercase
586 * @param bool $deleteUnused
587 * @param string $expected
588 * @dataProvider substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArrayDataProvider
589 */
590 public function substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArray($template, $markersAndSubparts, $wrap, $uppercase, $deleteUnused, $expected) {
591 $this->assertSame($expected, HtmlParser::substituteMarkerAndSubpartArrayRecursive($template, $markersAndSubparts, $wrap, $uppercase, $deleteUnused));
592 }
593
594 /**
595 * @return array
596 */
597 public function cDataWillRemainUnmodifiedDataProvider() {
598 return array(
599 'single-line CDATA' => array(
600 '/*<![CDATA[*/ <hello world> /*]]>*/',
601 '/*<![CDATA[*/ <hello world> /*]]>*/',
602 ),
603 'multi-line CDATA #1' => array(
604 '/*<![CDATA[*/' . LF . '<hello world> /*]]>*/',
605 '/*<![CDATA[*/' . LF . '<hello world> /*]]>*/',
606 ),
607 'multi-line CDATA #2' => array(
608 '/*<![CDATA[*/ <hello world>' . LF . '/*]]>*/',
609 '/*<![CDATA[*/ <hello world>' . LF . '/*]]>*/',
610 ),
611 'multi-line CDATA #3' => array(
612 '/*<![CDATA[*/' . LF . '<hello world>' . LF . '/*]]>*/',
613 '/*<![CDATA[*/' . LF . '<hello world>' . LF . '/*]]>*/',
614 ),
615 );
616 }
617
618 /**
619 * @test
620 * @param string $source
621 * @param string $expected
622 * @dataProvider cDataWillRemainUnmodifiedDataProvider
623 */
624 public function xHtmlCleaningDoesNotModifyCDATA($source, $expected) {
625 $result = $this->subject->XHTML_clean($source);
626 $this->assertSame($expected, $result);
627 }
628
629 /**
630 * Data provider for spanTagCorrectlyRemovedWhenRmTagIfNoAttribIsConfigured
631 */
632 public static function spanTagCorrectlyRemovedWhenRmTagIfNoAttribIsConfiguredDataProvider() {
633 return array(
634 'Span tag with no attrib' => array(
635 '<span>text</span>',
636 'text'
637 ),
638 'Span tag with allowed id attrib' => array(
639 '<span id="id">text</span>',
640 '<span id="id">text</span>'
641 ),
642 'Span tag with disallowed style attrib' => array(
643 '<span style="line-height: 12px;">text</span>',
644 'text'
645 )
646 );
647 }
648
649 /**
650 * @test
651 * @param string $content
652 * @param string $expectedResult
653 * @dataProvider spanTagCorrectlyRemovedWhenRmTagIfNoAttribIsConfiguredDataProvider
654 */
655 public function tagCorrectlyRemovedWhenRmTagIfNoAttribIsConfigured($content, $expectedResult) {
656 $tsConfig = array(
657 'allowTags' => 'span',
658 'tags.' => array(
659 'span.' => array(
660 'allowedAttribs' => 'id',
661 'rmTagIfNoAttrib' => 1
662 )
663 )
664 );
665 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
666 }
667
668 /**
669 * @test
670 */
671 public function rmTagIfNoAttribIsConfiguredDoesNotChangeNestingType() {
672 $tsConfig = array(
673 'allowTags' => 'div,span',
674 'rmTagIfNoAttrib' => 'span',
675 'globalNesting' => 'div,span'
676 );
677 $content = '<span></span><span id="test"><div></span></div>';
678 $expectedResult = '<span id="test"></span>';
679 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
680 }
681
682 /**
683 * Data provider for localNestingCorrectlyRemovesInvalidTags
684 *
685 * @return array
686 */
687 public static function localNestingCorrectlyRemovesInvalidTagsDataProvider() {
688 return array(
689 'Valid nesting is untouched' => array(
690 '<B><I></B></I>',
691 '<B><I></B></I>'
692 ),
693 'Valid nesting with content is untouched' => array(
694 'testa<B>test1<I>test2</B>test3</I>testb',
695 'testa<B>test1<I>test2</B>test3</I>testb'
696 ),
697 'Superflous tags are removed' => array(
698 '</B><B><I></B></I></B>',
699 '<B><I></B></I>'
700 ),
701 'Superflous tags with content are removed' => array(
702 'test1</B>test2<B>test3<I>test4</B>test5</I>test6</B>test7',
703 'test1test2<B>test3<I>test4</B>test5</I>test6test7'
704 ),
705 'Another valid nesting test' => array(
706 '<span><div></span></div>',
707 '<span><div></span></div>',
708 ),
709 );
710 }
711
712 /**
713 * @test
714 * @dataProvider localNestingCorrectlyRemovesInvalidTagsDataProvider
715 * @param string $content
716 * @param string $expectedResult
717 */
718 public function localNestingCorrectlyRemovesInvalidTags($content, $expectedResult) {
719 $tsConfig = array(
720 'allowTags' => 'div,span,b,i',
721 'localNesting' => 'div,span,b,i',
722 );
723 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
724 }
725
726 /**
727 * Data provider for globalNestingCorrectlyRemovesInvalidTags
728 *
729 * @return array
730 */
731 public static function globalNestingCorrectlyRemovesInvalidTagsDataProvider() {
732 return array(
733 'Valid nesting is untouched' => array(
734 '<B><I></I></B>',
735 '<B><I></I></B>'
736 ),
737 'Valid nesting with content is untouched' => array(
738 'testa<B>test1<I>test2</I>test3</B>testb',
739 'testa<B>test1<I>test2</I>test3</B>testb'
740 ),
741 'Invalid nesting is cleaned' => array(
742 '</B><B><I></B></I></B>',
743 '<B></B>'
744 ),
745 'Invalid nesting with content is cleaned' => array(
746 'test1</B>test2<B>test3<I>test4</B>test5</I>test6</B>test7',
747 'test1test2<B>test3test4</B>test5test6test7'
748 ),
749 'Another invalid nesting test' => array(
750 '<span><div></span></div>',
751 '<span></span>',
752 ),
753 );
754 }
755
756 /**
757 * @test
758 * @dataProvider globalNestingCorrectlyRemovesInvalidTagsDataProvider
759 * @param string $content
760 * @param string $expectedResult
761 */
762 public function globalNestingCorrectlyRemovesInvalidTags($content, $expectedResult) {
763 $tsConfig = array(
764 'allowTags' => 'span,div,b,i',
765 'globalNesting' => 'span,div,b,i',
766 );
767 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
768 }
769
770 /**
771 * @return array
772 */
773 public function emptyTagsDataProvider() {
774 return array(
775 array(0 , NULL, FALSE, '<h1></h1>', '<h1></h1>'),
776 array(1 , NULL, FALSE, '<h1></h1>', ''),
777 array(1 , NULL, FALSE, '<h1>hallo</h1>', '<h1>hallo</h1>'),
778 array(1 , NULL, FALSE, '<h1 class="something"></h1>', ''),
779 array(1 , NULL, FALSE, '<h1 class="something"></h1><h2></h2>', ''),
780 array(1 , 'h2', FALSE, '<h1 class="something"></h1><h2></h2>', '<h1 class="something"></h1>'),
781 array(1 , 'h2, h1', FALSE, '<h1 class="something"></h1><h2></h2>', ''),
782 array(1 , NULL, FALSE, '<div><p></p></div>', ''),
783 array(1 , NULL, FALSE, '<div><p>&nbsp;</p></div>', '<div><p>&nbsp;</p></div>'),
784 array(1 , NULL, TRUE, '<div><p>&nbsp;&nbsp;</p></div>', ''),
785 array(1 , NULL, TRUE, '<div>&nbsp;&nbsp;<p></p></div>', ''),
786 array(1 , NULL, FALSE, '<div>Some content<p></p></div>', '<div>Some content</div>'),
787 array(1 , NULL, TRUE, '<div>Some content<p></p></div>', '<div>Some content</div>'),
788 array(1 , NULL, FALSE, '<div>Some content</div>', '<div>Some content</div>'),
789 array(1 , NULL, TRUE, '<div>Some content</div>', '<div>Some content</div>'),
790 array(1 , NULL, FALSE, '<a href="#skiplinks">Skiplinks </a><b></b>', '<a href="#skiplinks">Skiplinks </a>'),
791 array(1 , NULL, TRUE, '<a href="#skiplinks">Skiplinks </a><b></b>', '<a href="#skiplinks">Skiplinks </a>'),
792 );
793 }
794
795 /**
796 * @test
797 * @dataProvider emptyTagsDataProvider
798 * @param bool $stripOn TRUE if stripping should be activated.
799 * @param string $tagList Comma seperated list of tags that should be stripped.
800 * @param bool $treatNonBreakingSpaceAsEmpty If TRUE &nbsp; will be considered empty.
801 * @param string $content The HTML code that should be modified.
802 * @param string $expectedResult The expected HTML code result.
803 */
804 public function stripEmptyTags($stripOn, $tagList, $treatNonBreakingSpaceAsEmpty, $content, $expectedResult) {
805 $tsConfig = array(
806 'keepNonMatchedTags' => 1,
807 'stripEmptyTags' => $stripOn,
808 'stripEmptyTags.' => array(
809 'tags' => $tagList,
810 'treatNonBreakingSpaceAsEmpty' => $treatNonBreakingSpaceAsEmpty
811 ),
812 );
813
814 $result = $this->parseConfigAndCleanHtml($tsConfig, $content);
815 $this->assertEquals($expectedResult, $result);
816 }
817
818 /**
819 * Calls HTMLparserConfig() and passes the generated config to the HTMLcleaner() method on the current subject.
820 *
821 * @param array $tsConfig The TypoScript that should be used to generate the HTML parser config.
822 * @param string $content The content that should be parsed by the HTMLcleaner.
823 * @return string The parsed content.
824 */
825 protected function parseConfigAndCleanHtml(array $tsConfig, $content) {
826 $config = $this->subject->HTMLparserConfig($tsConfig);
827 return $this->subject->HTMLcleaner($content, $config[0], $config[1], $config[2], $config[3]);
828 }
829
830 /**
831 * @return array
832 */
833 public function removeFirstAndLastTagDataProvider() {
834 return array(
835 array('<span>Wrapper<div>Some content</div></span>', 'Wrapper<div>Some content</div>'),
836 array('<td><tr>Some content</tr></td>', '<tr>Some content</tr>'),
837 array('Something before<span>Wrapper<div>Some content</div></span>Something after', 'Wrapper<div>Some content</div>'),
838 array('<span class="hidden">Wrapper<div>Some content</div></span>', 'Wrapper<div>Some content</div>'),
839 array('<span>Wrapper<div class="hidden">Some content</div></span>', 'Wrapper<div class="hidden">Some content</div>'),
840 );
841 }
842
843 /**
844 * Removes the first and last tag in the string
845 * Anything before the first and after the last tags respectively is also removed
846 *
847 * @test
848 * @dataProvider removeFirstAndLastTagDataProvider
849 * @param string $str String to process
850 * @param string $expectedResult
851 */
852 public function removeFirstAndLastTag($str, $expectedResult) {
853 $this->assertEquals($expectedResult, $this->subject->removeFirstAndLastTag($str));
854 }
855 }